C#泛型,限制特定结构

Ben*_*Ben 5 c# generics struct

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

这是可以的,我相信:

string Add<T>(object value, T expiration) where T : struct; 
Run Code Online (Sandbox Code Playgroud)

但这不是出现:

string Add<T>(object value, T expiration) where T : Struct1, Struct2; 
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Jer*_*Gee 7

不,因为结构是密封的(您不能创建ValueType的子类).

相反,请考虑让您的结构实现一个接口,然后将其用作约束,如下所示:

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

  • 你不能在你不能控制的结构上强制执行新接口(`DateTime`,`TimeSpan`等),所以不能:你不能这样做. (2认同)
  • 如果要执行此操作,则需要在自定义结构或类中包装(装饰)DateTime或TimeSpan.在实践中,听起来有两个Add()重载在这里会更好:添加(对象值,TimeSpan到期)和Add(对象值,DateTime到期).无论如何,你的代码在两种情况下都会有所不同...... (2认同)

Eri*_*ert 7

泛型的目的是制作通用的方法和类型,因此得名.如果您只有两个可能的类型参数,那么只需编写两个方法.

还要记住,C#泛型不是C++模板.当你在类型参数上调用一个方法时,比方说,对于每个类型参数的构造,该方法调用将是完全相同的方法调用.这是通用的.它不是一个模板,编译器编译代码两次,三次,一次,每种类型参数一次,并重新计算方法调用的每一个.

所以,即使你可以将你的类型参数限制为两种类型,那对你有什么好处呢?所有你可以调用它们的方法是它们通过它们的基类Object共同拥有的方法.在这种情况下,您有一个适用于所有对象的通用方法,那么为什么要将它限制为两种类型呢?


Mar*_*ell 5

我希望过载是你最好的选择:

string Add(object value, MyStruct1 expiration) {...}
string Add(object value, MyStruct2 expiration) {...}
Run Code Online (Sandbox Code Playgroud)

因为你不能继承一个结构,因而,这更适合只有可行的T在您的例子 MyStruct1MyStruct2可能也有具体的方法,然后- .

将泛型重新限制为多种引用类型; 不是真的-即使有,命名为"添加",暗示你想使用运营商的支持,这并不在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
}
Run Code Online (Sandbox Code Playgroud)

(在.NET 3.5)另一种选择是使用Operator支持MiscUtil,使用Operator.AddOperator.AddAlternative.