将通用T限制为特定类型

Mig*_*ura 3 c# generics

我有以下方法:

public static IResult<T, String> Validate<T>(this T value) {
} // Validate
Run Code Online (Sandbox Code Playgroud)

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

Sco*_*ain 6

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

以下是进行重载的方法。

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<Int64, 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
Run Code Online (Sandbox Code Playgroud)

这是通过使用一个通用接口,您列出的所有成员实现的IConvertible,这样您就可以受其限制,但这将允许任何 IConvertible 而不仅仅是您列出的 5 个。

public static IResult<T, String> Validate<T>(this T value) where IConvertible {
} // Validate
Run Code Online (Sandbox Code Playgroud)


Sjo*_*888 5

你只能这样做:

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

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

  • 在这种情况下,泛型在这里没有任何好处,因为你无法从int派生出来 (4认同)

Jaa*_*rus 5

将泛型限制为一组特定类型是不可用的。但其他类型的约束是。使用泛型最接近您想要实现的目标是添加以下约束:

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

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

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

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