为了账号安全,请及时绑定邮箱和手机立即绑定

属性辅助方法的 c# 泛型

属性辅助方法的 c# 泛型

C#
森林海 2022-12-24 12:55:28
我找不到在 .Net Core 中实现此 DRY 的好方法。(不要重复自己)。我怎样才能做到不重复大部分逻辑?以下是 2 种方法:    public static string GetCategory(this Enum val)    {        CategoryAttribute[] attributes = (CategoryAttribute[])val            .GetType()            .GetField(val.ToString())            .GetCustomAttributes(typeof(CategoryAttribute), false);        return attributes.Length > 0 ? attributes[0].Category : string.Empty;    }    public static string GetDescription(this Enum val)    {        DescriptionAttribute[] attributes = (DescriptionAttribute[])val            .GetType()            .GetField(val.ToString())            .GetCustomAttributes(typeof(DescriptionAttribute), false);        return attributes.Length > 0 ? attributes[0].Description : string.Empty;    }
查看完整描述

3 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

我会从这个开始:


public static T GetAttribute<T>(this Enum val)

    where T : Attribute

{

    return (T)val

    .GetType()

    .GetField(val.ToString())

    .GetCustomAttribute(typeof(T), false);

}

将您的方法变成这样:


public static string GetCategory(this Enum val)

{

    return val.GetAttribute<CategoryAttribute>()?.Category ?? string.Empty;

}



public static string GetDescription(this Enum val)

{

    return val.GetAttribute<DescriptionAttribute>()?.Description ?? string.Empty;

}

可以说你可以做更多的事情来让那些最终的方法更干一点,但我猜你在这里使用的模式(从属性中获取属性并返回它的值或空字符串)可能不够普遍值得专门为此创建一个方法。GetAttribute另一方面,该方法可能具有更高的可重用性。


查看完整回答
反对 回复 2022-12-24
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

您可以使用GetCustomAttribute<T>instead 的通用版本,它可以将代码简化到不需要 IMO 的另一个抽象的地方。


public static string GetCategory(this Enum val)

{

    return val.GetType()

          .GetField(val.ToString())

          .GetCustomAttribute<CategoryAttribute>(false)?.Category ?? string.Empty;

}


public static string GetDescription(this Enum val)

{

    return val.GetType()

          .GetField(val.ToString())

          .GetCustomAttribute<DescriptionAttribute>(false)?.Description ?? string.Empty;

}



查看完整回答
反对 回复 2022-12-24
?
波斯汪

TA贡献1811条经验 获得超4个赞

在 C# 7.3 中,您可以将方法限制为枚举类型。这将为您节省一箱枚举。


public static class AttributeExtensions

{

    public static string GetCategory<T>(this T val) where T: Enum

    {

        return GetAttr<CategoryAttribute, T>(val)?.Category ?? "";

    }


    public static string GetDescription<T>(this T val) where T : Enum

    {

        return GetAttr<DescriptionAttribute, T>(val)?.Description ?? "";

    }


    private static TAttr GetAttr<TAttr, T>(this T val) where TAttr : Attribute

    {

        return (TAttr)typeof(T)

            .GetField(val.ToString())

            ?.GetCustomAttributes(typeof(TAttr), false)

            ?.FirstOrDefault();

    }

}

此外,在使用反射时,缓存性能很重要:


public static class AttributeExtensions

{

    private class EnumMetadata

    {

        public CategoryAttribute CategoryAttribute { get; set; }

        public DescriptionAttribute DescriptionAttribute { get; set; }

    }


    private class EnumMetadataCache<T> where T : Enum

    {

        private static readonly ConcurrentDictionary<T, EnumMetadata> MetadataCache = new ConcurrentDictionary<T, EnumMetadata>();


        public static EnumMetadata GetMetadata(T item)

        {

            return MetadataCache.GetOrAdd(item, val =>

                new EnumMetadata

                {

                    CategoryAttribute = GetAttr<CategoryAttribute, T>(val),

                    DescriptionAttribute = GetAttr<DescriptionAttribute, T>(val)

                }

            );

        }

    }


    public static string GetCategory<T>(this T val) where T : Enum

    {

        return EnumMetadataCache<T>.GetMetadata(val).CategoryAttribute?.Category ?? "";

    }


    public static string GetDescription<T>(this T val) where T : Enum

    {

        return EnumMetadataCache<T>.GetMetadata(val).DescriptionAttribute?.Description ?? "";

    }


    private static TAttr GetAttr<TAttr, T>(this T val) where TAttr : Attribute

    {

        return (TAttr)typeof(T)

            .GetField(val.ToString())

            ?.GetCustomAttributes(typeof(TAttr), false)

            ?.FirstOrDefault();

    }

}


查看完整回答
反对 回复 2022-12-24
  • 3 回答
  • 0 关注
  • 121 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号