在C#中使用Attributes(特性)来控制枚举成员是否应该被序列化或映射

发布时间 2023-04-12 14:12:28作者: Tammytan

如果标记了[NonSerialized]特性,会防止将该字段序列化。但是,该字段仍然可以用于foreach迭代,因为它仍然是枚举的有效成员。
如果要防止特定枚举成员被foreach迭代,用[NonSerialized]特性是不起作用的。相反,可以创建一个自定义的Attribute继承自System.Attribute,并将其应用到需要隐藏的枚举成员上。在枚举上使用[Flags]特性也将防止它被foreach迭代。
以下是一个示例,防止枚举成员被foreach迭代:

[Flags]
public enum SampleEnum
{
    abc,
    def,
    [EnumIteratorIgnore]
    efg
}

[AttributeUsage(AttributeTargets.Field)]
public class EnumIteratorIgnoreAttribute : Attribute { }

public static IEnumerable<SampleEnum> GetEnumValues()
{
    foreach (SampleEnum e in Enum.GetValues(typeof(SampleEnum)))
    {
        if (e.GetType()
             .GetField(e.ToString())
             .GetCustomAttributes(typeof(EnumIteratorIgnoreAttribute), true)
             .Length == 0)
        {
            yield return e;
        }
    }
}

 

在这个示例中,SampleEnum类型被标记为[Flags],这意味着它是一个位标记,不能直接用于foreach迭代。此外,egf枚举成员上定义了一个自定义的EnumIteratorIgnoreAttribute特性,该特性将防止该成员被迭代。
在枚举类型上定义了一个GetEnumValues()方法,该方法遍历枚举类型的所有值,并使用反射来查找每个值的自定义特性。如果枚举值上未发现EnumIteratorIgnoreAttribute特性,则枚举值将被yield返回,否则将被忽略。
因此,在foreach循环中使用GetEnumValues()方法来获取枚举类型的所有值,而忽略在枚举成员上定义了EnumIteratorIgnoreAttribute特性的值。