> I have 2 general c# questions I was hoping someone could answer...
>
> 1. Is it possible to return a struct by ref?...
> 2. is it possible to call a constructor with a base class?...
>
[quoted text clipped - 6 lines]
> object myo = MethodThatReturnsObjectOfBOrC();
> A mya = new mya(myo);

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
thanks for the info.
>If you want reference type semantics, make the type involved a
>reference type.
Yes it looks like that is the best way. Its just sometimes I like creating
structs for simple datatypes such as...
struct MyData
{
public MyData(int x, int y) {...}
int X;
int Y;
}
then is there not a difference in this statement when its a struct vs class...
MyData[] _data = new MyData[10];
you would either be creating 10 MyData pointers or 10 MyData. so i think
there is definite value in being able to return by ref especially for
efficiency.
> No. There'd be no compile-time guarantee that you wouldn't be passing
> in something completely different. Overloading is performed at compile
> time, not execution time.
I think I can accomplish the runtime binding by using reflection...
ConstructorInfo ci = typeof(myobject).GetConstructor(new Type[] {
myitem.GetType() });
if (ci == null)
{
throw ...
}
newobject = ci.Invoke(new object[] {myitem});
of course this is different then casting at compile time like you said but
accomplishes the runtime constructor selection.
Thanks again for the info.
> > I have 2 general c# questions I was hoping someone could answer...
> >
[quoted text clipped - 49 lines]
>
> No. Casting is a mostly compile-time construct.
Peter Duniho - 17 Mar 2008 19:06 GMT
>> If you want reference type semantics, make the type involved a
>> reference type.
[quoted text clipped - 9 lines]
> int Y;
> }
But if you want to pass an instance of that data structure around using
reference semantics, you should be using a reference type (i.e. a class).
Which is what Jon wrote.
> then is there not a difference in this statement when its a struct vs
> class...
>
> MyData[] _data = new MyData[10];
There is a difference, yes. With a struct, each element of the array is
initialized to the default value for the struct, whereas for a class, each
element of the array is initialized with null and you'd have to explicitly
create a new instance of your class for each array element.
That said, it's not really all that difficult to perform that
initialization. It's a little more work than initializing an array of
value types, but it's not like it's a big deal.
> you would either be creating 10 MyData pointers or 10 MyData. so i think
> there is definite value in being able to return by ref especially for
> efficiency.
Well, for better or worse, C# makes a very clear delineation between value
types and reference types. For reasonably small structs (and IMHO, that
describes all good structs), returning the struct by value would not
create a perceptible loss of efficiency.
Besides, even if C# offered a way to return a struct by reference, the
struct is still fundamentally a value type. So as soon as you try to use
that reference you're going to wind up copying the data, incurring the
exact same performance penalty (if any) that returning it by value might
have caused.
The bottom line, just as Jon already pointed out, if you want to treat
your data using reference semantics, you need to make it a reference type.
>> No. There'd be no compile-time guarantee that you wouldn't be passing
>> in something completely different. Overloading is performed at compile
>> time, not execution time.
>
> I think I can accomplish the runtime binding by using reflection...
Maybe. But IMHO it would be better to provide a static factory method in
the class in question that incorporates the switch logic. For example:
class A
{
public A(B b) { }
public A(C c) { }
public static A FromObject(object obj)
{
if (obj is B)
{
return new A((B)obj);
}
else if (obj is C)
{
return new A((C)obj);
}
else
{
// handle error, e.g. throw exception or return null
}
}
}
You'd just call it like this:
object obj = ReturnsBOrC();
A a = A.FromObject(obj);
Then at least any code that might not know what object it's using to
instantiate A doesn't need to repeat that logic. It's also clearer than
using reflection, and probably performs better too.
Pete
Jon Skeet [C# MVP] - 17 Mar 2008 20:28 GMT
> thanks for the info.
>
[quoted text clipped - 10 lines]
> int Y;
> }
Why? What makes you prefer a struct in that case?
> then is there not a difference in this statement when its a struct vs class...
>
> MyData[] _data = new MyData[10];
>
> you would either be creating 10 MyData pointers or 10 MyData.
When MyData is a struct, that will create 10 instances of MyData
(although effectively for free - just clearing enough memory).
When MyData is a class, the array will be initialized with null
references.
> so i think there is definite value in being able to return by ref
> especially for efficiency.
As I said before, there's no such concept in C# - you *pass* by
reference, but "return by reference" is meaningless. You could return a
pointer, which is a similar concept, but it wouldn't be the same.
I would avoid worrying about efficiency without doing actual
measurements though.
> > No. There'd be no compile-time guarantee that you wouldn't be passing
> > in something completely different. Overloading is performed at compile
[quoted text clipped - 12 lines]
> of course this is different then casting at compile time like you said but
> accomplishes the runtime constructor selection.
It's interesting that you worry about the efficiency of returning data
"by value" vs "by reference", but you are willing to use reflection for
constructor calls. I know which is more likely to have a significant
performance impact...
Seriously, try to avoid doing this - the code will be significantly
harder to follow. Design your way out of needing it, if at all
possible.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Jarlaxle - 17 Mar 2008 21:09 GMT
> > thanks for the info.
> >
[quoted text clipped - 34 lines]
> I would avoid worrying about efficiency without doing actual
> measurements though.
I really don't understand why you say "return by reference" is meaningless.
if you can pass by reference then returning by reference is the same thing.
I understand though that there is no concept in c#.
> > > No. There'd be no compile-time guarantee that you wouldn't be passing
> > > in something completely different. Overloading is performed at compile
[quoted text clipped - 21 lines]
> harder to follow. Design your way out of needing it, if at all
> possible.
well you assume I was talking about the same application. or even the same
part of an application. there is a time for efficiency and a time for
extensibility.
Jon Skeet [C# MVP] - 17 Mar 2008 21:20 GMT
> > I would avoid worrying about efficiency without doing actual
> > measurements though.
>
> I really don't understand why you say "return by reference" is meaningless.
> if you can pass by reference then returning by reference is the same thing.
Well, I find it hard to see how it could be the *same* thing.
Passing by reference means that the parameter and argument are aliased.
A change to one variable is immediately reflected in the other.
Now, this is always feasible because while the called method is
executing the calling method is still present - so the argument can't
just vanish.
What would happen if you returned a local variable when "returning by
ref"? The variable would have gone by the time the method completed. Or
would that be disallowed? Or would the variable have been captured.
Maybe it isn't completely meaningless - but I'd certainly rather live
without it, personally.
> > It's interesting that you worry about the efficiency of returning data
> > "by value" vs "by reference", but you are willing to use reflection for
[quoted text clipped - 8 lines]
> part of an application. there is a time for efficiency and a time for
> extensibility.
True, I was making that assumption. I can't say I'd want either
solution in code I was trying to maintain, however.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Willy Denoyette [MVP] - 17 Mar 2008 21:41 GMT
>> > I would avoid worrying about efficiency without doing actual
>> > measurements though.
[quoted text clipped - 16 lines]
> ref"? The variable would have gone by the time the method completed. Or
> would that be disallowed? Or would the variable have been captured.
In that case of a value type (which is what we are discussing right?), that
would mean that, or:
- the callee would need to allocate the "value" on the heap (but not the GC
heap) instead of on the stack, or,
- the callee would have to copy the stack allocated "value" to the heap and
return a pointer to that "value" .
For obvious reasons, I must say I don't like none of these.
Willy.
Ben Voigt [C++ MVP] - 18 Mar 2008 16:38 GMT
>>> I would avoid worrying about efficiency without doing actual
>>> measurements though.
[quoted text clipped - 19 lines]
> Maybe it isn't completely meaningless - but I'd certainly rather live
> without it, personally.
Not having it is a royal pain. What does this code do (assume the index i
refers to an element that exists)?
struct Abc {
int a;
double b;
string c;
}
Abcs[i].a = 15;
Well, it depends on whether Abcs is an array or a list, and IMHO that is
just plain stupid.
Jon Skeet [C# MVP] - 18 Mar 2008 16:40 GMT
<snip>
> > Maybe it isn't completely meaningless - but I'd certainly rather live
> > without it, personally.
>
> Not having it is a royal pain.
Can't say I remember *ever* wanting it.
> What does this code do (assume the index i
> refers to an element that exists)?
[quoted text clipped - 9 lines]
> Well, it depends on whether Abcs is an array or a list, and IMHO that is
> just plain stupid.
Well, at least it will fail to compile if it's a list, rather than just
silently failing to do anything.
The moral is to avoid mutable value types though...

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk