将通用T限制为特定类型

时间:2015-06-13 14:31:07

标签: c# generics

我有以下方法:

public static IResult<T, String> Validate<T>(this T value) {
} // Validate

如何将T限制为Int16,Int32,Int64,Double和String?

3 个答案:

答案 0 :(得分:5)

你只能这样做:

public static IResult<T, String> Validate<T>(this T value) where T: int
{
    //validate
} 

只有类和接口可以用作约束。

答案 1 :(得分:2)

这种对泛型的限制是不可用的。您可以通过泛型获得的最接近的是添加以下约束:

public static IResult<T, String> Validate<T>(this T value) 
    : where T IConvertible, IComparable, IComparable<T>, IEquatable<T>
{
    // Validate
}

所有原始类型都实现了这些接口。要进一步限制,唯一的选择是在运行时检查类型,如果不匹配则抛出异常:

Type type = typeof(T);
if (type != typeof(Int16) &&
    type != typeof(Int32) &&
    type != typeof(Int64) &&
    type != typeof(Double) &&
    type != typeof(String))
{
    throw new ArgumentException();
}

这不是最好的解决方案,但至少它会为您提供一些编译时安全性和运行时安全性。

答案 2 :(得分:2)

您不能以这种方式限制泛型,您只能选择一个类作为约束。您必须要么进行5次重载或找到一个接口,所有这5个共享并使用它。您选择哪个选项取决于Validate doe。

以下是如何进行重载。

public static IResult<Int16, String> Validate<T>(this Int16 value) {
} // Validate

public static IResult<Int32, String> Validate<T>(this Int32 value) {
} // Validate

public static IResult<Int54, String> Validate<T>(this Int64 value) {
} // Validate

public static IResult<double, String> Validate<T>(this double value) {
} // Validate

public static IResult<String, String> Validate<T>(this String value) {
} // Validate

这是通过使用一个通用界面,您列出的所有成员都实施IConvertible,因此您可以限制,但这将允许任何IConvertible,而不仅仅是您列出的5。

public static IResult<T, String> Validate<T>(this T value) where IConvertible {
} // Validate