C# 我如何告诉编译器我的泛型肯定会允许“|=”或强制转换为int?
我是C语言中泛型的新手,我正在尝试创建一个使用泛型的方法。在尝试创建局部变量时,我遇到了where关键字,因此我确信它将成为解决方案的一部分 原因是我有几个不同的枚举变量,但该方法会对每个给定的字符串(该字符串是枚举定义的值之一)执行相同的操作,将其打开,使用类似于位字段的枚举 我把其中的大部分放在一起,我现在陷入困境的部分是能够告诉泛型方法允许|=是可以的,因为我确定传入的任何类型都将支持操作符 如果可能的话,我希望能够保持通用性,因此可以是枚举或列表,并且我将根据类型执行不同的代码路径 我正在做的事情的例子C# 我如何告诉编译器我的泛型肯定会允许“|=”或强制转换为int?,c#,generics,C#,Generics,我是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到int的转换,我认为Bruno的方法是可行的。从C4开始,不可能表示枚举通用约束。也不可能表示运算符约束 也就是说,我认为您正在寻找这样一种方法:
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以外的底层类型的枚举。我将尝试类似以下伪代码的方法:
[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;
}
不幸的是,这是不可能的 您可以使用struct约束来限制值类型,但显然它包含的不止是整数。然后,您唯一可以做的就是在代码的早期检查实际类型 支持的约束条件在中进行了描述
您不能执行运算符约束-请参见如果将枚举someType用作一组位标志,则应使用[Flags]属性标记该枚举someType。@asawyer我是否只需将[Flags]放在每个枚举声明之前?请参见Bruno Silva的回答,他标记了枚举。在这种特殊情况下,您可能还需要查看:-基本上,.net支持标志枚举解析,以逗号分隔的值表示。因此,您只需从MyIdentifier创建字符串,并将其传递给Enum.TryParseSo即可。。。如果我再次打破它:-对于几个枚举,我是在每个枚举之前放置[Flags],还是在声明列表的开头显示[Flags]就足够了?您应该将其放置在每个枚举声明之前。谢谢,这是一个很大的帮助。一个可能很明显的警告是,如果为枚举指定不同的基础类型,例如枚举someType:byte,这将在运行时失败,就像@Ani提到的解决方案一样。希望这不是问题,但值得注意。@Weeble值得注意,但今天不会给我带来问题。