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# / March 2008

Tip: Looking for answers? Try searching our database.

3 general c# questions

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jarlaxle - 17 Mar 2008 17:31 GMT
I have 2 general c# questions I was hoping someone could answer...

1.  Is it possible to return a struct by ref?...

class A
{
   private mystruct _ms = new mystruct();

   public mystruct ms
   {
       get { return _ms; }
   }
}

    since ms is a struct it returns a copy can therefore can't set values
on it.  I think you should be able to doe something like...

get { return ref _ms; }

Any reason why this is not possible or any workarounds instead of making a
class or exposing the member directly?

2.  is it possible to call a constructor with a base class?...

class A
{
   A(B obj) {...}
   A(C obj) {...}
}

object myo = MethodThatReturnsObjectOfBOrC();
A mya = new mya(myo);

Problem is I'd like to not know what could be returned from
MethodThatReturnsObjectOfBOrC so I'd like to avoid a switch statement. (could
add new types in future).

is it possible to cast at runtime and have the constructor address resolved
at runtime?...

Type t = myo.GetType();
A mya = new mya((t)myo);

Thanks.
Jon Skeet [C# MVP] - 17 Mar 2008 17:54 GMT
> I have 2 general c# questions I was hoping someone could answer...
>
> 1.  Is it possible to return a struct by ref?...

No. There's no such concept as "return by reference".

> class A
> {
[quoted text clipped - 13 lines]
> Any reason why this is not possible or any workarounds instead of making a
> class or exposing the member directly?

If you want reference type semantics, make the type involved a
reference type.

> 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);

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.

> Problem is I'd like to not know what could be returned from
> MethodThatReturnsObjectOfBOrC so I'd like to avoid a switch statement. (could
[quoted text clipped - 5 lines]
> Type t = myo.GetType();
> A mya = new mya((t)myo);

No. Casting is a mostly compile-time construct.

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 18:39 GMT
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

Ben Voigt [C++ MVP] - 17 Mar 2008 18:28 GMT
> I have 2 general c# questions I was hoping someone could answer...
>
> 1.  Is it possible to return a struct by ref?...

Not in C#.  C++/CLI can...

> class A
> {
[quoted text clipped - 37 lines]
>
> Thanks.
Jarlaxle - 17 Mar 2008 18:44 GMT
thanks...yes i'm so used to c++ pointers and references it seemed it should
be possible.

do you think it was left out to distinguish value/ref types in c# or do you
think it may be added in the future?

> > I have 2 general c# questions I was hoping someone could answer...
> >
[quoted text clipped - 43 lines]
> >
> > Thanks.
Ben Voigt [C++ MVP] - 17 Mar 2008 18:57 GMT
> thanks...yes i'm so used to c++ pointers and references it seemed it
> should be possible.
>
> do you think it was left out to distinguish value/ref types in c# or
> do you think it may be added in the future?

I think you may be able to return a pointer in C# if you use the 'unsafe'
keyword.  The C++/CLI compiler probably generates the same IL.

What I don't like about the .NET implementation of pointers is that it
considers all pointers to be unsafe.... they aren't.  Only casting or
pointer arithmetic (that results in a new pointer) break type safety.

>>> I have 2 general c# questions I was hoping someone could answer...
>>>
[quoted text clipped - 43 lines]
>>>
>>> Thanks.
Barry Kelly - 17 Mar 2008 21:28 GMT
> What I don't like about the .NET implementation of pointers is that it
> considers all pointers to be unsafe.... they aren't.  Only casting or
> pointer arithmetic (that results in a new pointer) break type safety.

Or pointers to stack-allocated objects that escape their activation
record - which would be easily doable when returning a reference, akin
to returning a ref to a temporary in C++.

Also, interior pointers are only allowed on the stack in the CLR AFAIK,
and so the GC probably has special knowledge that isn't generalized -
you wouldn't be able to store those pointers in fields on the heap. It's
likely performance concerns that causes the GC to only support them in
locals.

Within those constraints, pointers are indeed type-safe. But those
constraints are pretty constraining: they effectively limit the use of
pointers to just being references to (the start of) value types, where
pointers are themselves value types. If one needs pointers within those
constraints, just use a reference type instead. It's not a large extra
cost.

-- Barry

Signature

http://barrkel.blogspot.com/


Rate this thread:







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.