问题描述
在我的代码中有很多地方我需要遍历枚举值来做某事。所以为了简单明了,我想转换一下,比如下面这段代码
foreach (string name in Enum.GetNames(typeof(myEnum)))
{
chart1.Series[$"Series{name}*"].Enabled = optParams[(myEnum)Enum.Parse(typeof(myEnum),name)];
}
进入
typeof(myEnum).ForEach((name,value) =>
{
chart1.Series[$"Series{name}*"].Enabled = optParams[value];
});
我试过这种扩展方法:
public static void ForEach<T>(this T t,Action<string,T> action) where T : Enum
{
foreach (string name in Enum.GetNames(typeof(T)))
{
action(value,(T)Enum.Parse(typeof(T),name));
}
}
但是当我如上调用它时,编译器无法识别 e
,因此抛出此错误:CS1503 Argument 1: cannot convert from 'System.Type' to 'myEnum'
。
如果我改变调用方式——这次明确指定 T 的类型(两次?)——
typeof(myEnum).ForEach<myEnum>((name,value) =>
{
chart1.Series[$"Series{name}*"].Enabled = optParams[value];
});
然后错误将更改为 CS1929 'Type' does not contain a deFinition for 'ForEach'…
。
我该如何解决这个问题?
更新: 提出@Tim 的建议,我将扩展方法更改为
public static void ForEach<T>(this Type t,name));
}
}
它的工作原理就像
typeof(myEnum).ForEach<myEnum>((name,value) =>
{
chart1.Series[$"Series{name}*"].Enabled = optParams[value];
});
然而,正如@Olivier 指出的那样,问题是我从未在我的扩展方法中使用过 t
。扩展方法可以写成
public static void ForEach2<T>(this Type t,T> action) where T : Enum
{
foreach (var value in Enum.GetValues(t))
{
action(Enum.GetName(t,value),(T)value);
}
}
但还是要以typeof(myEnum).ForEach<myEnum>()
的格式调用。
UPDATE2:
正如@Olivier 澄清的那样,这里没有必要使用扩展方法,因为它不打算在枚举的实例上调用它,因此可以使用像下面这样的普通 static
方法来完成。>
public static class Enums
{
public static void ForEach<T>(Action<string,T> action) where T : Enum
{
foreach (string name in Enum.GetNames(typeof(T)))
{
action(value,name));
}
}
}
然后
Enums.ForEach<myEnum>((name,value) => {…});
解决方法
正如您所发现的,您可以通过站立来做您想做的事情(并确保您的两个类型规范对齐;如果 {{1} } 与 typeof(T)
不匹配)。
问题是你不能创建静态扩展方法。您只能在实例上调用扩展方法。因此,例如,我可以执行以下操作:
t
但是,我只能在枚举类型的实例上调用它,而不能在类型名称本身上调用它。因此,例如,这有效:
public static void Foreach<T>(this T anEnum,Action<string,T> action) where T : struct,Enum
{
foreach (var name in Enum.GetNames(typeof(T)))
{
Enum.TryParse<T>(name,out var val);
action(name,val);
}
}
后跟此代码:
public enum ATestEnum
{
A,Test,Enum
}
但是,由于不能在 ATestEnum.Test.Foreach((name,val) => Debug.WriteLine($"Name: {name},Value: {val}"));
上调用它,所以必须在 ATestEnum
的实例上调用它(在本例中为 ATestEnum
)。这很麻烦,因为它作用于枚举类型的所有实例。人生就是这样。