如何从多个属性的自定义属性获取特定数据

时间:2015-07-09 19:08:32

标签: c# .net properties attributes

我对属性不熟悉所以我想要实现的目标可能是不可能的。根据我的理解,属性用于在编译时将数据绑定到特定的方法,属性,类等。

我的属性非常简单,定义如下:

public class MyClass
{
    [NowThatsAnAttribute(HeresMyString = "A" )]
    public string ThingyA
    {
        get;
        set;
    }

    [NowThatsAnAttribute(HeresMyString = "B" )]
    public string ThingyB
    {
        get;
        set;
    }
}

我有两个使用相同自定义属性的属性,如下所示:

private void MyMethod()
{
    string something = "";

    var props = typeof (MyClass).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(NowThatsAnAttribute)));

    //this is where things get messy
    //here's sudo code of what I want to do
    //I KNOW THIS IS NOT VALID SYNTAX
    foreach(prop in props)
    {
        //my first idea was this
        if(prop.attribute(NowThatsAnAttribute).HeresMyString == "A")
        {
            something = "A";
        } 
        else if(prop.attribute(NowThatsAnAttribute).HeresMyString == "B")
        {
            something = "B";
        }

        //my second idea was this
        if(prop.Name == "ThingyA")
        {
            something = "A";
        } 
        else if(prop.Name == "ThingyB")
        {
            something = "B";
        }
    }

    //do stuff with something
}

这一切都运行正常,花花公子,但我试图从另一种方法访问这些属性的属性,并根据属性的值设置某些数据。

这就是我现在正在做的事情:

something

问题是StackFrame始终被设置为" B"我知道是由于循环通过属性。我不确定如何访问与特定属性的属性关联的值。我感觉这是一种非常明显的做法,我只是没有看到。

我已尝试使用config/initializers/session_store.rb,但在我现在附近的同一地点结束。

注意:使用.Net 4.0。

注意2:MyMethod是我无法编辑的界面的一部分,因此我无法传递任何参数或任何内容。

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

如果您传递特定属性的名称,您将能够获取正确的属性值:

private string MyMethod(string propName)
{
    PropertyInfo pi = typeof (MyClass).GetProperty(propName);
    if (pi == null)
        return null;
    var a = (NowThatsAnAttribute)pi.GetCustomAttribute(typeof(NowThatsAnAttribute));
    if (a!=null)
        return a.HeresMyString;
    return null;
}

MyMethod("ThingyA")返回A

答案 1 :(得分:0)

Reflection还为您提供了属性的名称。

Type t = typeof(MyClass);
PropertyInfo[] props = t.GetProperties();
foreach (PropertyInfo p in props) {
    NowThatsAnAttribute attr = p.GetCustomAttributes(false)
        .OfType<NowThatsAnAttribute>()
        .FirstOrDefault();
    if (attr != null) {
        string propName = p.Name;
        string attrValue = attr.HeresMyString;
        switch (propName) {
            case "ThingyA":
                //TODO: Do something for ThingyA
                break;
            case "ThingyB":
                //TODO: Do something for ThingyB
                break;
            default:
                break;
        }
    }
}

您还可以将信息添加到字典中:

var dict = new Dictionary<string, string();
...
if (attr != null) {
    string propName = p.Name;
    string attrValue = attr.HeresMyString;
    dict.Add(propName, attrValue);
}
...

获得一些道具的价值

string value = dict["ThingyA"];

答案 2 :(得分:0)

你可以这样做一般的方法:

    static object GetAttributeValue<T, A>(string attribName, string propName = "") where A : Attribute
    {
        object[] attribs = null;

        if (string.IsNullOrEmpty(propName))
            attribs = typeof(T).GetCustomAttributes(true);

        else
        {
            PropertyInfo pi = typeof(T).GetProperty(propName);
            if (pi == null)
                return null;
            attribs = pi.GetCustomAttributes(true);
        }

        A a = null;
        foreach (object attrib in attribs)
        {
            if (attrib is A)
            {
                a = attrib as A;
                break;
            }
        }

        if (a != null)
        {
            var prop = a.GetType().GetProperty(attribName);
            return prop.GetValue(a, null);
        }
        return null;
    }

然后你会这样称呼它:

object value = GetPropertyAttributeValue<MyClass,NowThatsAnAttribute>("HeresMyString", "ThingyA");

所以你的&#34; MyMethod&#34;可能看起来像这样:

private void MyMethod()
{
    string something = "";

    var props = typeof (MyClass).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(NowThatsAnAttribute)));

    //this is where things get messy
    //here's sudo code of what I want to do
    //I KNOW THIS IS NOT VALID SYNTAX
    foreach(prop in props)
    {
        string attribVal = object value = GetPropertyAttributeValue<MyClass,NowThatsAnAttribute>("HeresMyString", prop.Name);
        //my first idea was this
        if(attribVal == "A")
        {
            something = "A";
        } 
        else if(attribVal == "B")
        {
            something = "B";
        }

    }

    //do stuff with something
}

这将允许您重用相同的方法来从不同的类中获取不同属性(或直接在类上跳过第二个参数的属性)上的不同属性的属性值。