开发者

Do you gain any operations when you constrain a generic type using where T : struct?

This may be a bit of an abstract question, so apologies in advance.

I am looking into generics in .NET, and was wondering about the where T : struct constraint.

I understand that this allows you to restrict the type used to be a value type. My question is, without any type constraint, you can do a limited number of operations on T.

Do you gain the ability to use any additional operations when you specify where T : struct, or is the only value in restricting the types you can pass in?

Edit

Some interesting answers so far, thanks. I guess the question I am actually asking is that if i were to write,开发者_如何转开发 (in a discussion about how to use generics),

"Now that you have constrained the type argument to value types, you can also do ___________________ on/with objects of that type"

Is there anything to put in that blank? I can think of things for the other constraints, but not this one.


All that T : struct gains you is an implicit new() constructor, and a few obvious things involving null. Perhaps more importantly, callers can't use classes, interfaces or Nullable<T>.

What types of operations are you after? For operators, try dynamic in 4.0, or MiscUtil in 3.5


The only thing that you gain relative to other possible sets of constraints is the ability to work with values of type Nullable<T> (which is why T: struct prohibits caller from passing Nullable<T> as a type parameter - it can't be nested).


No, you don't gain any operations on T by specifying the where T: struct generic type constraint. You constrain your callers to only specify value types (except Nullable<T> value types, which are not allowed).


One type of operation which is guaranteed not to be available with a mutable class and may sometimes be available with a mutable struct is the ability to copy the state of a thing using the assignment operator. Using mutating interfaces with structures is tricky, since attempting to use a mutating interface on a structure in a read-only context will yield code that compiles cleanly but does not work (I really wish compilers would recognize an attribute on struct and interface members that would indicate that they should not be usable on read-only structures). Nonetheless, there are some contexts where such a thing can be useful.

For example, if an algorithm required the ability to store the state of an enumerator and revert the enumerator to its saved state, and if the enumerator was a generic type TEnum constrained to both struct and IEnumerator<T>, it may be possible to copy theTEnumto a local variable of that type and then later copy it back. Note that this would work with some but not allstructtypes which implementIEnumerable; such a technique should in practice probably only be used with interfaces that explicitly document a requirement that all legitimate struct-type implementations must exhibit value semantics (IEnumerator` does not have such a documented requirement).

Note that the fact that code may use the ability to copy structs by value when it exists, that does preclude the possibility of a slightly-different (perhaps less-efficient) method using a class-type implementation of the interface. The function signatures:

void ActOnSequence<T>(T theEnumerator) where T:struct, IEnumerator<String>;
void ActOnSequence(IEnumerator<String> theEnumerator);

can co-exist and be used without difficulty. The former will be invoked on value-type implementations of the interface, while the latter will be invoked on heap-type implementations. Note that without the struct constraint, it would not be possible to have both of the above methods in scope and have the correct method invoked automatically.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜