我怎么能告诉编译器我的泛型肯定会允许"|=";或铸造到int

本文关键字:quot int 编译器 怎么能 我的 泛型 | 更新日期: 2023-09-27 18:26:12

我对C#中的泛型非常陌生,我正试图创建一个使用泛型的方法。当我试图创建一个局部变量时,偶然发现了where关键字,所以我确信它将是解决方案的一部分。

原因是我有几个不同的枚举变量,但该方法对每个变量都做相同的处理(给定一个字符串,该字符串是枚举的定义值之一,将其打开,使用类似位字段的枚举)。

我已经把大部分内容放在一起了,我现在所坚持的部分是能够告诉泛型方法允许"|="是可以的,因为我确信传入的任何类型都会支持运算符。

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

关于的示例

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;
}

我怎么能告诉编译器我的泛型肯定会允许"|=";或铸造到int

我会尝试这样的东西(伪代码):

[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;
}

从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以外的底层类型的枚举。

通常,没有很好的方法来调用泛型类型上的运算符,尽管在某些情况下有一些漏洞和解决方法可以提供帮助。

看到这个类似的问题:通用C#代码和加运算符

在这种情况下,由于您知道从int到int的枚举转换,我认为Bruno的方法是可行的。

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

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

支持的约束限制如所述http://msdn.microsoft.com/en-us/library/d5x73970.aspx

您不能执行运算符约束-请参阅.NET泛型中重载运算符约束的解决方案