如何在 C# 中访问属性或常量的描述属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/695730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:48:56  来源:igfitidea点击:

How to access the Description attribute on either a property or a const in C#?

c#.netattributes

提问by Metro Smurf

How do you access the Description property on either a const or a property, i.e.,

您如何访问 const 或属性上的 Description 属性,即,

public static class Group
{

    [Description( "Specified parent-child relationship already exists." )]
    public const int ParentChildRelationshipExists = 1;

    [Description( "User is already a member of the group." )]
    public const int UserExistsInGroup = 2;

}

or

或者

public static class Group
{

    [Description( "Specified parent-child relationship already exists." )]
    public static int ParentChildRelationshipExists { 
      get { return 1; } 
    }

    [Description( "User is already a member of the group." )]
    public static int UserExistsInGroup { 
      get { return 2; } 
    }

}

In the calling class I'd like to access the Description property, i.e.,

在调用类中,我想访问 Description 属性,即

int x = Group.UserExistsInGroup;
string description = Group.UserExistsInGroup.GetDescription(); // or similar

I'm open to ideas to other methodologies as well.

我也对其他方法的想法持开放态度。

EDIT:I should have mentioned that I've seen an example provided here: Do auto-implemented properties support attributes?

编辑:我应该提到我在这里看到了一个例子: Do auto-implemented properties support attributes?

However, I'm looking for a method to access the description attribute without having to enter a string literal into the property type, i.e., I'd rather not do this:

但是,我正在寻找一种无需在属性类型中输入字符串文字即可访问 description 属性的方法,即,我宁愿不这样做:

typeof(Group).GetProperty("UserExistsInGroup");

Something along the lines of an Extension Method; similar to the following method that will return the Description attribute on an Enum via an Extension Method:

与扩展方法类似的东西;类似于以下将通过扩展方法返回枚举上的描述属性的方法:

public static String GetEnumDescription( this Enum obj )
{
    try
    {
        System.Reflection.FieldInfo fieldInfo = 
            obj.GetType().GetField( obj.ToString() );

        object[] attribArray = fieldInfo.GetCustomAttributes( false );

        if (attribArray.Length > 0)
        {
            var attrib = attribArray[0] as DescriptionAttribute;

            if( attrib != null  )
                return attrib.Description;
        }
        return obj.ToString();
    }
    catch( NullReferenceException ex )
    {
        return "Unknown";
    }
}

采纳答案by Andy

You can call MemberInfo.GetCustomAttributes()to get any custom attributes defined on a member of a Type. You can get the MemberInfofor the property by doing something like this:

您可以调用MemberInfo.GetCustomAttributes()来获取定义在Type. 您可以MemberInfo通过执行以下操作来获取属性:

PropertyInfo prop = typeof(Group).GetProperty("UserExistsInGroup",
    BindingFlags.Public | BindingFlags.Static);

回答by JaredPar

Try the following

尝试以下

var property = typeof(Group).GetProperty("UserExistsInGroup");
var attribute = property.GetCustomAttributes(typeof(DescriptionAttribute), true)[0];
var description = (DescriptionAttribute)attribute;
var text = description.Description;

回答by Ilya Tchivilev

Okay, I've seen your edit, I'm not sure you can do it with extension methods, as they would be anaware of the type of the containing class.

好的,我看过你的编辑,我不确定你可以用扩展方法来做,因为他们会知道包含类的类型。

This is going to sound a little wacky, but how about creating a new class a "DescribedInt", which would have an implicit cast operator to let you use it as an int automatically? You'll be able to use pretty much how you describe. You'll still have a description, but when you need to use it like an Int, you wont' need to get the .Data property...

这听起来有点古怪,但是如何创建一个新类“DescribedInt”,它有一个隐式强制转换运算符,让您自动将其用作 int?你几乎可以使用你描述的方式。你仍然会有一个描述,但是当你需要像 Int 一样使用它时,你不需要获取 .Data 属性......

eg:

例如:

private void ExampleUse()
{
    int myvalue = Group.A; //see, no need to cast or say ".Data" - implicit cast
    string text = Group.A.Description;

//do stuff with values... }

// 用值做事... }

public static class Group
{
    public static DescribedInt A = new DescribedInt(12, "some description");
    public static DescribedInt B = new DescribedInt(88, "another description");
}

public class DescribedInt
{
    public readonly int data;
    public readonly string Description;

    public DescribedInt(int data, string description)
    {
        this.data = data;
        this.Description = description;
    }

    //automatic cast to int
    public static implicit operator int(DescribedInt orig)
    {
        return orig.data;
    }

    //public DescribedInt(string description)
    //{
    //    this.description = description;
    //}

    //if you ever need to go the "other way"
    //public static implicit operator DescribedInt(int orig)
    //{
    //    return new DescribedInt(orig, "");
    //}
}

回答by Maksym Kozlenko

Here is a helper class I am using for processing custom attributes in .NET

这是我用于处理 .NET 中的自定义属性的辅助类

public class AttributeList : List<Attribute>
{
    /// <summary>
    /// Gets a list of custom attributes
    /// </summary>
    /// <param name="propertyInfo"></param>
    /// <returns></returns>
    public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo)
    {
        var result = new AttributeList();
        result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>());
        return result;
    }

    /// <summary>
    /// Finds attribute in collection by its type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T FindAttribute<T>() where T : Attribute
    {
        return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType()));
    }

    public bool IsAttributeSet<T>() where T : Attribute
    {
        return FindAttribute<T>() != null;
    }
}

Also unit tests for MsTest showing how to use this class

MsTest 的单元测试也展示了如何使用这个类

[TestClass]
public class AttributeListTest
{
    private class TestAttrAttribute : Attribute
    {
    }

    [TestAttr]
    private class TestClass
    {
    }

    [TestMethod]
    public void Test()
    {
        var attributeList = AttributeList.GetCustomAttributeList(typeof (TestClass));
        Assert.IsTrue(attributeList.IsAttributeSet<TestAttrAttribute>());
        Assert.IsFalse(attributeList.IsAttributeSet<TestClassAttribute>());
        Assert.IsInstanceOfType(attributeList.FindAttribute<TestAttrAttribute>(), typeof(TestAttrAttribute));
    }
}

http://www.kozlenko.info/2010/02/02/getting-a-list-of-custom-attributes-in-net/

http://www.kozlenko.info/2010/02/02/getting-a-list-of-custom-attributes-in-net/