By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,462 Members | 1,484 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,462 IT Pros & Developers. It's quick & easy.

Problem with out parameters

P: n/a
Hi,

I want to make a class that acts like an "object factory", that
creates objects all inherited from a root class called MyBaseObject.
To create objects I want to use a method in which I pass in the first
parameter the object type I want to create, and in the second
parameter (an output parameter) the reference to the object created.

So, the method is declared like this:
public int GetObject(MyObjectTypes type, out MyBaseObject obj)

Suppose I have a class MyObject1 inherited from MyBaseObject.

In the client code that uses the GetObject method I want to do
something like this:

.... other lines of code ...
MyObject1 newObj;
Factory.GetObject(MyObjcectType.Object1, out newObj);
.... other lines of code ...

Using the code above, I get the following error at compilation time:
'argument 2: cannot convert from out MyObject1 to out MyBaseObject'.

I use this code to avoid the problem:

.... other lines of code ...
MyObject1 newObj;
MyBaseObject temp;

Factory.GetObject(MyObjcectType.Object1, out temp);
newObj = (MyObject1) temp;
.... other lines of code ...

Is there a way to force the c# compiler to accept the first version of
my code?

Thanks in advance for any suggestion

Bye
Gianluca
Nov 16 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
>Is there a way to force the c# compiler to accept the first version of
my code?


No

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #2

P: n/a
Gianluca <mo**********@hotmail.com> wrote:
I want to make a class that acts like an "object factory", that
creates objects all inherited from a root class called MyBaseObject.
To create objects I want to use a method in which I pass in the first
parameter the object type I want to create, and in the second
parameter (an output parameter) the reference to the object created.

So, the method is declared like this:
public int GetObject(MyObjectTypes type, out MyBaseObject obj)


What's it returning, and is it actually important? (You're ignoring it
in the calling code example you've given.) It seems quite odd to me
that a method called GetObject doesn't return an object of any
description in its normal returned value.

I suggest you change the signature to

public MyBaseObject GetObject (MyObjectTypes type)

That way you can just do:

MyObject1 newObj = (MyObject1) Factory.GetObject(MyObjectType.Object1);

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #3

P: n/a
> Is there a way to force the c# compiler to accept the first version
of my code?

As Mattias said, "No," and here is why.

Your method declares that it is returning a MyBaseObject in the out
variable, which means that it could return an actual MyBaseObject or
any object of a type derived from MyBaseObject, such as a MyObject1.

However, the calling method has no way of knowing what will be
returned. If it were to allow you to pass a MyObject1 as the out
argument, then the method could conceivably return an object of type
MyBaseObject, or MyObject2, or some other thing, and you would end up
breaking type safety. You would have a MyObject1 variable referring to
(pointing to) an object of a different type. Very bad!

As such, the compiler requires you to perform a specific act--a
cast--to assure it that you know the thing being returned is really a
MyObject1 and not anything else.

I suppose that the language designers could come up with some
nomenclature for a cast-and-out-argument all rolled into one, but it
seems unlikely that you'd often need something like that.

You can, of course, get around this by doing this:

public class Factory
{
public static void GetObject(MyObjectType type, out MyBaseObject
result)
{
...
}

public static void GetObject(MyObjectType type, out MyObject1 result)
{
MyBaseObject temp;
GetObject(type, out temp);
result = (MyObject1)temp;
}
}

....but then the "object type" argument seems superfluous, doesn't it,
so you could simply recode it like this:

public static void GetObject(out MyObject1 result)
{
MyBaseObject temp;
GetObject(MyObjectType.Object1, out temp);
result = (MyObject1)temp;
}

Note that this works only if you use "out" parameters... it won't work
with function results, because all of the methods would have the same
signature.

It also someone bastardizes the Factory pattern, because it means that
for every new derived type you implement, you have to create a new
nethod signature in the Factory. However, it does give you a more
convenient notation for calling the factory method.

Nov 16 '05 #4

P: n/a
mo**********@hotmail.com (Gianluca) wrote in message news:<56**************************@posting.google. com>...
Hi,

[...]

Thanks to all for your help.
I know that what I'm trying to do is possibile in VB.NET, so I thought
that I could do it in that way also in C#.

Anyway, I will take into consideration your suggestions.

Bye
Nov 16 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.