Does C# generics support type signature constraints?
One of the benefits with C++ templates is that you (implicitly) can require a certain type signature (e.g. type T needs to have a function x that takes no parameters and returns an int). Does C# generics support something similar?
开发者_运维百科I am aware of constraints based on base class or interface but this is not what I am looking for.
(As a C++ programmer learning C# I might be mistaken that this is a feature that you would want in C#. Any comments on this would be appriciated as well...)
Nothing except for the constraints you have already seen (which do, to be fair, cover a lot of common scenarios). There are some common workarounds:
dynamic
, in 4.0- manual duck-typing using either reflection or IL generation etc
none of these have static type-checking etc, though.
Yes, through an interface. You can define a generic object that has a type that must have a specific interface implemented. Within that interface, you would essentially be forcing any object added to that generic, list for instance, to have a specific signature.
Whether or not that's what you're not looking for, that's how you accomplish it. :)
No, this is not possible. It's mainly caused by the differences between C++ templates and C# generics:
When you compile C++ template, the resulting code has types like vector<int>
and vector<string>
. This means the compiler has to know all the possible type parameters, but it also means it can check them for correctness.
When you compile C# generic type, you are actually creating just one generic type: List<T>
. Because of this, the C# compiler doesn't have to know all the possible types at compile type, which means you can have generic types in binary libraries, which is not possible with C++. But this also means that you can't check all the types. To be able to do something like that, there are constraints, but they can't do several things C++'s compile time checking can, like checking the presence of certain methods (without using interface or some base class) or the presence of suitable operators.
In C# 4, you can achieve effect somewhat similar to this kind of templates using dynamic
, but this does no compile-time checking, which means you lose safety – you can put in a type that doesn't have the appropriate members and you won't find out until you reach that line of code at runtime.
No. This is what interface
s are for. Create an interface
that defined the contract you want to enforce in the type constraints. Then specify that in the constraints.
Nope, not supported in c#. Like you said, the closest thing requires you to have the classes implement a common interface.
You could try to mimic the behavior with reflection, by looking for the method by the signature, but that's a runtime constraint, and not a compile-time constraint.
There are 5 types of constraints you can put onto generics in .Net:
- Derivation constraints state the ascendancy of a type parameter.
- Interface constraints are interfaces that are implemented by the type parameter.
- Value type constraints restrict a type parameter to a value type.
- Reference type constraints restrict a type parameter to a reference type.
- Constructor constraints stipulate that the type parameter has a default or parameterless constructor.
This page shows more information.
No, C# does not have constraints like that.
As you know, generic constraints can only enforce inheritance of a base class or an interface, or a few other constraints (constructor constraint new()
, reference type constraint class
, value type constraint struct
).
You might be able to achieve your desired behavior using delegates, and there are many Generic delegates available.
For example, Func<int>
is a delegate that takes no parameters and returns an int
. Func<string, DateTime, int>
takes a string
and DateTime
and returns an int
, etc...
精彩评论