Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / December 2005

Tip: Looking for answers? Try searching our database.

out Parameter And Base Class ?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
dahuzizyd - 22 Dec 2005 01:22 GMT
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

Nicholas Paldino [.NET/C# MVP] - 22 Dec 2005 03:57 GMT
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.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> Hi all:
> I think I had a problem with using out parameter , why the instance of
[quoted text clipped - 37 lines]
> thanks in advance
> Yadong Zhao
dahuzizyd - 22 Dec 2005 04:29 GMT
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
Jon Skeet [C# MVP] - 22 Dec 2005 06:43 GMT
> 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
[quoted text clipped - 11 lines]
> 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.

Signature

Jon Skeet - <skeet@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

Joanna Carter [TeamB] - 22 Dec 2005 07:43 GMT
| 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

Signature

Joanna Carter [TeamB]
Consultant Software Engineer

Jon Skeet [C# MVP] - 22 Dec 2005 07:54 GMT
> | 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 )
> |  {
[quoted text clipped - 6 lines]
> 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.

Signature

Jon Skeet - <skeet@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

Joanna Carter [TeamB] - 22 Dec 2005 08:24 GMT
| 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
[quoted text clipped - 4 lines]
| 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

Signature

Joanna Carter [TeamB]
Consultant Software Engineer

Jon Skeet [C# MVP] - 22 Dec 2005 08:53 GMT
> | 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
[quoted text clipped - 8 lines]
> 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)
>     {
[quoted text clipped - 10 lines]
> 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 :)

Signature

Jon Skeet - <skeet@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

dahuzizyd - 22 Dec 2005 08:04 GMT
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(deriveClassType);
 }
 public void WriteName()
 {
  Console.WriteLine(this.ToString());
 }
}
class DeriveClass : BaseClass
{
}
class DeriveClass2 : BaseClass
{
}

Thanks and  Regards
Yadong Zhao
dahuzizyd - 22 Dec 2005 09:10 GMT
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
Jon Skeet [C# MVP] - 22 Dec 2005 09:17 GMT
> Thanks for your answer .
>
[quoted text clipped - 4 lines]
> 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.

Signature

Jon Skeet - <skeet@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

Joanna Carter [TeamB] - 22 Dec 2005 09:26 GMT
| 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

Signature

Joanna Carter [TeamB]
Consultant Software Engineer


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.