微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

循环遍历枚举并运行通用操作的扩展方法

如何解决循环遍历枚举并运行通用操作的扩展方法

在我的代码中有很多地方我需要遍历枚举值来做某事。所以为了简单明了,我想转换一下,比如下面这段代码

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)。这很麻烦,因为它作用于枚举类型的所有实例。人生就是这样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。