我如何告诉编译器我的泛型肯定会允许“| =”或转换为int?

时间:2012-02-29 15:42:11

标签: c# generics

我是C#中泛型的新手,我正在尝试创建一个使用泛型的方法。在尝试创建局部变量时,我跳过了where关键字,因此我确信它将成为解决方案的一部分。

这样做的原因是我有几个不同的枚举变量但是方法对每个变量都是一样的(给定一个字符串是枚举的定义值之一,使用枚举就像位字段一样切换它)。 / p>

我将大部分内容放在一起,我现在坚持的部分是能够告诉泛型方法可以允许“| =”,因为我确定传入的任何类型都将支持运算符。

我希望能够保持通用性,如果可能的话,可以是enum或List,我会根据类型执行不同的代码路径。

我正在采取的实例

enum someType { value1 = 1<<0, value2 = 1<<1, value3 = 1<<2 }; // and so on
// some more enums

private T someMethod<T>(string myIdentifyers) 
    where T: new()
{
    // suppose myIdentifiers is 1 more more of the valid enum options
    // assume that the correct strings and enum combinations will be passed
    T retval = new T();

    while () {
    // assume a loop with a method call that parses off one identifyer at a time
        // if I have to convert the enum to an int first, so be it, but
        // at this point I can't tell it that a cast to int exists
        retval |= (T)System.Enum.Parse( typeof(T), oneIdentifyer, false );
    }

    return retval;
}

4 个答案:

答案 0 :(得分:3)

我会尝试这样的事情(伪代码):

[Flags]
enum someType { value1 = 1<<0, value2 = 1<<1, value3 = 1<<2 }; // and so on
// some more enums

private T someMethod<T>(string myIdentifyers) 
    where T: struct, new()
{
           // check if enum
    if (typeof(T).BaseType != typeof(Enum)) // we should probably check for the flags attribute too
            throw new Exception();

    // suppose myIdentifiers is 1 more more of the valid enum options
    // assume that the correct strings and enum combinations will be passed
    int retval = 0;

    while () {
    // assume a loop with a method call that parses off one identifyer at a time
        // if I have to convert the enum to an int first, so be it, but
        // at this point I can't tell it that a cast to int exists
        retval |= (int) (object) System.Enum.Parse( typeof(T), oneIdentifyer, false );
    }

    return (T) (object) retval;
}

答案 1 :(得分:1)

一般来说,在泛型类型上调用运算符没有好办法,尽管在某些情况下可以提供一些帮助和解决方法。

请参阅此类似问题:Generic C# Code and the Plus Operator

在这种情况下,既然你知道你的枚举转换为int,我认为布鲁诺的方法是可行的。

答案 2 :(得分:1)

从C#4开始,不可能表达enum泛型约束。也不可能表达运算符约束。

那就是说,我认为你正在寻找这样的方法:

public static T AssembleFlagsEnum<T>(IEnumerable<string> names) where T : struct
{
    return (T)(object)names.Aggregate(0, 
       (valSoFar, name) => valSoFar | Convert.ToInt32(Enum.Parse(typeof(T), name)));
}

请注意,这不会验证该类型是[Flags]枚举。它也不适用于具有int以外的基础类型的枚举。

答案 3 :(得分:0)

不幸的是,这是不可能的。

您可以使用 struct 约束来限制值类型,但显然包含的不仅仅是整数。您可以做的唯一事情是在代码的早期检查实际类型。

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

描述了支持的约束限制

您不能执行运算符约束 - 请参阅Solution for overloaded operator constraint in .NET generics