471,605 Members | 1,542 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,605 software developers and data experts.

out Parameter And Base Class ?

Hi all:
I think I had a problem with using out parameter , why the instance of
'SubClass' can't convert to 'BaseClass' ? my code is :
----------------------------------------------
using System;

namespace ConsoleApplication2
{

class Class1
{
[STAThread]
static void Main(string[] args)
{
SubClass y = new SubClass() ;
Test( out y);
}

static void Test( out BaseClass y )
{
Console.WriteLine(y.ToString());
}
}
class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass");
}
}
class SubClass : BaseClass
{
public SubClass()
{
Console.WriteLine("SubClass");
}
}
}
thanks in advance
Yadong Zhao
Dec 22 '05 #1
11 3324
dahuzizyd,

The reason you get this is because y needs to be of type BaseClass. If
you derived another class from BaseClass, say, SubClass2, then the Test
method could assign the parameter y to an instance of SubClass2. Upon
return, the variable y would not be able to be assigned to, because it is of
type SubClass2, not SubClass.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"dahuzizyd" <da********@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...
Hi all:
I think I had a problem with using out parameter , why the instance of
'SubClass' can't convert to 'BaseClass' ? my code is :
----------------------------------------------
using System;

namespace ConsoleApplication2
{

class Class1
{
[STAThread]
static void Main(string[] args)
{
SubClass y = new SubClass() ;
Test( out y);
}

static void Test( out BaseClass y )
{
Console.WriteLine(y.ToString());
}
}
class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass");
}
}
class SubClass : BaseClass
{
public SubClass()
{
Console.WriteLine("SubClass");
}
}
}
thanks in advance
Yadong Zhao

Dec 22 '05 #2
Thanks for your help .
My english is so bad that I can't show my problem clearly : - (

I write this code to make the Test method can reusnable. All class which
derived from BaseClass can be a parameter for this method.But if I write
like this:

BaseClass y ;
Test( out y);

static void Test( out BaseClass y )
{
y = new SubClass();
Console.WriteLine(1);
}

this code can be compiled . But the BaseClass will mean nothing.. If I don't
use the out word,everything is good.
So I think there are some thing that I never knew with the out word.

class Class1
{
[STAThread]
static void Main(string[] args)
{
DeriveClass y ;
Test( out y);

DeriveClass s = new DeriveClass();
DeriveClass2 s1 = new DeriveClass2();
Test1(s);
Test1(s1);
}
static void Test( out BaseClass y )
{
y = new DeriveClass();
Console.WriteLine(1);
}
static void Test1 ( BaseClass y )
{
Console.WriteLine(2);
}
}
class BaseClass
{
}
class DeriveClass : BaseClass
{

}
class DeriveClass2 : BaseClass
{

}
thanks in advance
Yadong Zhao

Dec 22 '05 #3
dahuzizyd <da********@hotmail.com> wrote:
Thanks for your help .
My english is so bad that I can't show my problem clearly : - (
No, I think you showed your problem fine.
I write this code to make the Test method can reusnable. All class which
derived from BaseClass can be a parameter for this method.But if I write
like this:

BaseClass y ;
Test( out y);

static void Test( out BaseClass y )
{
y = new SubClass();
Console.WriteLine(1);
}

this code can be compiled . But the BaseClass will mean nothing.. If I don't
use the out word,everything is good.
Indeed.
So I think there are some thing that I never knew with the out word


It's exactly as Nick said. You can't use a variable of a different type
(even if it's a subclass) for an "out" argument. Your Test method (in
your first post) could create a new instance of BaseClass (or a
different subclass) instead of SubClass - and at that stage, when the
method compiled, the variable wouldn't have the right kind of value.

This is specified in the C# language spec as:
<quote>
When a formal parameter is an output parameter, the corresponding
argument in a method invocation must consist of the keyword out
followed by a variable-reference of the same type as the formal
parameter.
</quote>

See http://www.pobox.com/~skeet/csharp/parameters.html for more
information about parameter passing.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 22 '05 #4
"dahuzizyd" <da********@hotmail.com> a ecrit dans le message de news:
%2****************@TK2MSFTNGP15.phx.gbl...

| Hi all:
| I think I had a problem with using out parameter , why the instance of
| 'SubClass' can't convert to 'BaseClass' ? my code is :

I think this could be a misleading message; there is definitely a problem
with the following :

| static void Test( out BaseClass y )
| {
| Console.WriteLine(y.ToString());
| }

You cannot call any methods on y until you have assigned a valid instance to
it.

The out parameter means that the reference passed in *has* to be initialised
as it is assumed to be null. The purpose of the out modifier is to allow the
same funtionality as returning a reference from a function and should be
treated as such. Its purpose is to return references from a method not to
pass references into it.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 22 '05 #5
Joanna Carter [TeamB] <jo****@not.for.spam> wrote:
"dahuzizyd" <da********@hotmail.com> a ecrit dans le message de news:
%2****************@TK2MSFTNGP15.phx.gbl...

| I think I had a problem with using out parameter , why the instance of
| 'SubClass' can't convert to 'BaseClass' ? my code is :

I think this could be a misleading message; there is definitely a problem
with the following :
It's not a misleading message - it's just that there are multiple
things wrong with the code.
| static void Test( out BaseClass y )
| {
| Console.WriteLine(y.ToString());
| }

You cannot call any methods on y until you have assigned a valid instance to
it.

The out parameter means that the reference passed in *has* to be initialised
as it is assumed to be null.
No - it's not assumed to be null. It's not definitely assigned. Big
difference :) If it were assumed to be null, you wouldn't get a
compile-time error, you'd get a NullReferenceException at run-time.
The purpose of the out modifier is to allow the
same funtionality as returning a reference from a function and should be
treated as such. Its purpose is to return references from a method not to
pass references into it.


Indeed. The reason the OP is getting the error message, however, is
that the actual argument must be a variable of exactly the same type as
the output parameter.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 22 '05 #6
"Jon Skeet [C# MVP]" <sk***@pobox.com> a écrit dans le message de news:
MP************************@msnews.microsoft.com...

| No - it's not assumed to be null. It's not definitely assigned. Big
| difference :) If it were assumed to be null, you wouldn't get a
| compile-time error, you'd get a NullReferenceException at run-time.

You are right, it's early and my brain isn't yet communicating clearly :-)

| > The purpose of the out modifier is to allow the
| > same funtionality as returning a reference from a function and should be
| > treated as such. Its purpose is to return references from a method not
to
| > pass references into it.
|
| Indeed. The reason the OP is getting the error message, however, is
| that the actual argument must be a variable of exactly the same type as
| the output parameter.

Agreed. I think the problem is that the OP does not yet understand what the
out modifier actually does.

private void TestOut(out BaseClass value)
{
value.Test();
}

This code actually raise two errors :

Error 1 Use of unassigned out parameter 'value' F:\Test\Form1.cs 31 7 Test
Error 2 The out parameter 'value' must be assigned to before control leaves
the current method F:\Test\Form1.cs 29 18 Test

So the OP's examples definitely won't compile for other reasons than the
faulty parameter type. These errors make it clear that an out parameter
*must* be assigned something and not used to pass something in.

Can I wake up now ? :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 22 '05 #7
Joanna Carter [TeamB] <jo****@not.for.spam> wrote:
| No - it's not assumed to be null. It's not definitely assigned. Big
| difference :) If it were assumed to be null, you wouldn't get a
| compile-time error, you'd get a NullReferenceException at run-time.

You are right, it's early and my brain isn't yet communicating clearly :-)
No problem. I suspected you probably realised that, but thought it
would be worth clarifying it for the sake of everyone else :)
| > The purpose of the out modifier is to allow the
| > same funtionality as returning a reference from a function and should be
| > treated as such. Its purpose is to return references from a method not
to
| > pass references into it.
|
| Indeed. The reason the OP is getting the error message, however, is
| that the actual argument must be a variable of exactly the same type as
| the output parameter.

Agreed. I think the problem is that the OP does not yet understand what the
out modifier actually does.
Quite possibly. The reason you can't use an out argument of a derived
type is probably the most subtle part of it, to be honest.
private void TestOut(out BaseClass value)
{
value.Test();
}

This code actually raise two errors :

Error 1 Use of unassigned out parameter 'value' F:\Test\Form1.cs 31 7 Test
Error 2 The out parameter 'value' must be assigned to before control leaves
the current method F:\Test\Form1.cs 29 18 Test

So the OP's examples definitely won't compile for other reasons than the
faulty parameter type. These errors make it clear that an out parameter
*must* be assigned something and not used to pass something in.
Yup.
Can I wake up now ? :-)


Yup - go get some coffee :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 22 '05 #8
Thanks for your answer .

I think I understand.Before I write this code . I never pay attention to
this point of the out keyword.
:-(

Now , I rewrite my code to reach my purpose for reusnable. It's looks better
than before. :-)

My code is :
-----------------------------------------
class Class1
{
[STAThread]
static void Main(string[] args)
{
BaseClass y ;
Test( out y ,typeof(DeriveClass2) );
y.WriteName();
Console.ReadLine();
}
static void Test( out BaseClass y ,Type t )
{
y = BaseClass.CreateInstance(t);
}
}
class BaseClass
{
public static BaseClass CreateInstance(Type deriveClassType)
{
return (BaseClass)System.Activator.CreateInstance(deriveC lassType);
}
public void WriteName()
{
Console.WriteLine(this.ToString());
}
}
class DeriveClass : BaseClass
{
}
class DeriveClass2 : BaseClass
{
}

Thanks and Regards
Yadong Zhao

Dec 22 '05 #9
dahuzizyd <da********@hotmail.com> wrote:
Thanks for your answer .

I think I understand.Before I write this code . I never pay attention to
this point of the out keyword.
:-(

Now , I rewrite my code to reach my purpose for reusnable. It's looks better
than before. :-)


Good. It's worth avoiding out parameters where you can though,
preferring to use straight return values. That's simpler, and more
obvious.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 22 '05 #10
"dahuzizyd" <da********@hotmail.com> a ecrit dans le message de news:
OD*************@TK2MSFTNGP14.phx.gbl...

| Now , I rewrite my code to reach my purpose for reusnable. It's looks
better
| than before. :-)

In actual fact, what you are doing is implementing the Factory Method design
pattern.

Using an out parameter is not the usual way of doing this, at least for
returning a single instance of a given type.

You could just as well do this :

class Class1
{
[STAThread]
static void Main(string[] args)
{
BaseClass y = BaseClass.CreateInstance(typeof(DeriveClass2));
y.WriteName();
Console.ReadLine();
}
}

Or if you still feel that you need to have a Factory Method in Class1 as
well, then just use a method that returns an object of BaseClass type.

class Class1
{
static BaseClass Test(Type t )
{
return BaseClass.CreateInstance(t);
}

[STAThread]
static void Main(string[] args)
{
BaseClass y = Test(typeof(DeriveClass2));
y.WriteName();
Console.ReadLine();
}
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 22 '05 #11
This question is from our project . My origin code is an example for
project's code .
The project's framework design and coding is aleary finished . The desinger
and coder of the framework is at another country . So we have no chance to
change it and I think I must know the real reason for this. Thanks for your
help !

Thanks and Regards
Yadong Zhao

Dec 22 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Mysooru | last post: by
3 posts views Thread by Dave | last post: by
5 posts views Thread by Andreas Schmitt | last post: by
2 posts views Thread by Thomas Witkowski | last post: by
1 post views Thread by XIAOLAOHU | last post: by
reply views Thread by MichaelMortimer | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.