开发者

Slight confusion over reference types and value types in the C# spec

开发者 https://www.devze.com 2023-03-12 09:39 出处:网络
I\'m trying to digest this statement in the C# spec, which states (§4.2): A reference type is a class type, an interface type, an array type, or a delegate type.开发者_运维知识库

I'm trying to digest this statement in the C# spec, which states (§4.2):

A reference type is a class type, an interface type, an array type, or a delegate type.开发者_运维知识库

I know that structs can implement interfaces. And structs are value types.

So, I'm having trouble reconciling this information. Does this mean that structs behave as reference types when handled via an interface type? That would mean that you could get a reference to a value type...


Here's a blog post that may be illustrative.

http://blogs.msdn.com/b/abhinaba/archive/2005/10/05/477238.aspx

Yes, structs that implement interfaces get boxed as reference types if you handle them as interfaces, and yes, this can cause problems if you're not careful.


That's correct. When a value type is used in context where an interface reference is required, it gets boxed. Same thing happens if System.Object is required.

What you can't have is an interface reference to a value type instance on the stack, or inside another type. The boxing process creates a copy.


Yes, you can get a reference to a value type. Any time a value type is assigned to a variable or passed as a parameter to a method that expects an Object type, the value type is implicitly wrapped in an object instance - a process called boxing. Boxing is creating an object reference that contains a value. When the boxed object is assigned to or used like a value type, then it is unboxed and the value is extracted.


Yes, structs can implement an interface BUT they are not an interface type. A struct is a value type and when required will be boxed.


A struct which implements an interface will be boxed if it is cast to the interface, but not if it is cast to a generic type which is constrained to implement the interface. For example:

void Compare<T>(T thing1, T Thing2) where T:IComparable<T>
{
   return thing1.CompareTo(Thing2);
}

Note that while the above code avoids boxing when using structs, comparing two objects of value-type T will require three copy operations. If the parameters were passed by reference instead of by value, performance with value types would be enhanced, at the expense of impaired reference-type performance (and, of course, compatibility with the existing IComparable<T> and IComparer<T>).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号