将自动实现的属性的属性传递给其字段

时间:2015-09-30 18:14:06

标签: c# properties attributes field

我遇到以下问题:我想在第一步中将属性添加到类prop的自动实现的属性Foo中。 在第二步中,我迭代Foo的所有字段,并将值复制到这些字段(也可以找到并复制自动实现的属性字段的值)。在这部分中,我需要访问属性的信息。

class FieldSetter
{
    // This Method is called from outside and should work for any class
    private void SetFieldValues(object unknownObject)
    {
        foreach (var field in
                unknownObject.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                                       BindingFlags.Static).Where((field) => !field.IsLiteral))
        {
            if (!EvalAttribute(Attribute.GetCustomAttributes(field))) // the Attribute should be accessed here
            {
                // Do something if no special Information is set
                field.SetValue(a, "default Value");
            }

            else
            {
                // Do special things
                field.SetValue(a, "special Value");
            }
        }

    }


    internal static bool EvalAttribute(Attribute[] attributes)
    {

        foreach (System.Attribute attr in attributes)
        {
            var myAttr = attr as MyAttribute;
            if (myAttr != null)
            {
                if (myAttr.SomeAttributeValues == "Specific Attribute Value")
                {
                    return true;
                }
            }
        }
        return false;
    }
}

// This class is a example for how a given Object can look like
class Foo
{
    [MyAttribute("Example Information")] // This Attribute won't be accessed via prop-Field
    int prop { get; set; }

    [MyAttribute("Another Example Information")] // This Attribute won't be accessed via prop-Field
    int field;

    //... lots of other fields and properties
}


[System.AttributeUsage(System.AttributeTargets.All)]
class MyAttribute : Attribute
{
    public MyAttribute(string someInformation)
    {
        SomeAttributeValues = someInformation;
    }

    public string SomeAttributeValues;
}

2 个答案:

答案 0 :(得分:1)

你不能这样做。如果您需要在该字段上具有该属性,则需要自己声明该字段,而不是使用自动属性。或者,您可以在查找属性时反映属性。

答案 1 :(得分:0)

如果您可以保证您感兴趣的属性将始终自动实现,并且您已经知道将使用什么编译器来编译您感兴趣的类型,那么您可以利用以下事实:自动生成的属性的支持字段遵循特定的命名约定。例如,您提供的代码最终会出现如下字段名称:

<prop>k__BackingField

这是一个独特的名称,不能由C#代码直接生成,所以如果你遇到一个这样名字的字段,你可以从尖括号之间解析属性名称,并使用GetProperty()在那个名字上。

然而,这是一个hacky解决方案,因为:

  1. 用于支持字段的名称是一个实现细节,理论上可以在.NET的未来版本或Mono等替代编译器中进行更改。
  2. 没有什么可以确保您找到的字段始终与自动属性绑定。如果碰到这个,你会有什么期望?

    class Foo
    {
        int field;
    
        [MyAttribute("Example Information")]
        int prop { get{return field;} set {return field;} }
    
        //... lots of other fields and properties
    }
    
  3. 我强烈建议您花更多时间分析您的实际业务需求和约束,并了解是否有其他更可靠的方法来解决此问题。