是否可以约束泛化方法只接受特定类型的struct?
这是可以的,我相信:
string Add<T>(object value, T expiration) where T : struct;
但是看起来不是这样:
string Add<T>(object value, T expiration) where T : Struct1, Struct2;
注意:我希望将其约束为的结构是DateTime或TimeSpan,因此我无法控制它们。
由于
答案 0 :(得分:7)
不,因为结构是密封的(您不能创建ValueType的子类)。
相反,请考虑让您的结构实现一个接口,然后将其用作约束,如下所示:
string Add<T>(object value, T expiration) where T : struct, IMyInterface
答案 1 :(得分:7)
泛型的目的是创建泛型的方法和类型,因此命名。如果您只有两个可能的类型参数,那么只需编写两个方法。
还要记住,C#泛型不是C ++模板。当您在类型参数上调用方法时,例如,该方法调用将是与类型参数的每个构造完全相同的方法调用。这是通用。它不是一个模板,编译器编译代码两次,三次,一次,每种类型参数一次,并重新计算方法调用的每一个。
所以,即使你可以将你的类型参数限制为两种类型,那对你有什么好处呢?所有你可以调用它们的方法是它们通过它们的基类Object共同拥有的方法。在这种情况下,您有一个适用于所有对象的通用方法,那么为什么要将它限制为两种类型?
答案 2 :(得分:5)
我希望过载是你最好的选择:
string Add(object value, MyStruct1 expiration) {...}
string Add(object value, MyStruct2 expiration) {...}
这更合适,因为您不能对结构进行子类化,因此示例中的仅可行T
将 MyStruct1
和MyStruct2
- 可能还有具体的方法。
重新将泛型限制为多种引用类型;不是真的 - 即使有,“Add”这个名字也暗示你要使用运营商支持,也不在C#(3.0)中。
但是,在C#4.0中,dynamic
可能是一个选项 - 这可以作为鸭子打字的优化形式;你不会得到编译器支持(验证等),但它应该工作。您将在方法中转换为dynamic
:
string Add<T>(object value, T expiration) where T : struct {
dynamic valueDyn = value;
valueDyn += expiration; // or similar
// more code
}
另一个选项(在.NET 3.5中)是使用Operator
support中的MiscUtil,使用Operator.Add
或Operator.AddAlternative
。
答案 3 :(得分:-3)
我认为两者都不行,结构不是有效约束。用作约束的类型必须是接口,非密封或类型参数