C#泛型,对特定结构的约束

时间:2009-11-29 11:39:20

标签: c# generics struct

是否可以约束泛化方法只接受特定类型的struct?

这是可以的,我相信:

string Add<T>(object value, T expiration) where T : struct; 

但是看起来不是这样:

string Add<T>(object value, T expiration) where T : Struct1, Struct2; 

注意:我希望将其约束为的结构是DateTime或TimeSpan,因此我无法控制它们。

由于

4 个答案:

答案 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 MyStruct1MyStruct2 - 可能还有具体的方法。

重新将泛型限制为多种引用类型;不是真的 - 即使有,“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.AddOperator.AddAlternative

答案 3 :(得分:-3)

我认为两者都不行,结构不是有效约束。用作约束的类型必须是接口,非密封或类型参数