C#访问所有者对象的自定义属性

时间:2017-04-19 12:18:53

标签: c# system.reflection

  

如何访问父对象或所有者对象的自定义属性。   查看SQLFieldInfo结构的FieldInfo属性

     

这是一个更详细的程序,它将编译和运行,显示我需要的东西。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        Employee myclass = new Employee();

        // Load from sql server...
        myclass.Name = "Alain";
        myclass.Age = 51;
        //----

        MessageBox.Show(myclass.Name.ToString()); // Should return Alain
        MessageBox.Show(myclass.Age.FieldInfo.Type.ToString()); // Should output "int"
    }
}

// This next class is generated by a helper exe that reads SQL table design and create the class from it
[SQLTableAttribute(DatabaseName = "Employees", Schema = "dbo", TableName = "Employees")]
public class Employee
{
    [SQLFieldAttribute(FieldName = "ID", Type = SqlDbType.Int)]
    public SQLFieldInfo<int> ID { get; set; }

    [SQLFieldAttribute(FieldName = "Name", Type = SqlDbType.NVarChar, Size = 200)]
    public SQLFieldInfo<String> Name { get; set; }

    [SQLFieldAttribute(FieldName = "Age", Type = SqlDbType.Int)]
    public SQLFieldInfo<int> Age { get; set; }
}


public struct SQLFieldInfo<T>
{

    private readonly T value;

    public SQLFieldInfo(T Value) 
    {
        this.value = Value;
    }


    public static implicit operator SQLFieldInfo<T>(T Value)
    {
        return new SQLFieldInfo<T>(Value);
    }


    public T Value
    {
        get
        {
            return this.value;
        }
    }


    public override string ToString()
    {
        return this.value.ToString();
    }


    public SQLFieldAttribute FieldInfo
    {
        get
        {
            // Need to retreive the attribute class of the parent or declaring member

            return null;
        }
    }
}

// Holds the sql field information
public class SQLFieldAttribute : Attribute
{
    public string FieldName { get; set; }
    public SqlDbType Type { get; set; }
    public bool AllowNull { get; set; }
    public int Size { get; set; }
}

// Holds the sql table information
public class SQLTableAttribute : Attribute
{
    public string DatabaseName { get; set; }
    public string Schema { get; set; } = "dbo";
    public string TableName { get; set; }
}

谢谢!

阿兰

3 个答案:

答案 0 :(得分:1)

首先,MSDN是你的朋友。

然后,如果您想获取祖先的属性,只需在方法的 inherit 标志中指定true

var attribute = typeof(A).GetProperty("myprop").GetCustomAttributes(true)
                       .OfType<MycustomAttrib>().FirstOrDefault();

答案 1 :(得分:1)

我的数据类如下(应该可以完全翻译为上面的A):

public class Foo 
{
    [Argument(Help = "Name", AssignmentDelimiter = "=")]
    public string Name
    {
        get;
        set;
    }
}

辅助类负责读取对象的属性值:

static public string GetCommandLineDelimiter<T>(Expression<Func<T>> property)
{
    if(property != null)
    {
        var memberExpression = (MemberExpression)property.Body;
        string propertyName = memberExpression.Member.Name;
        PropertyInfo prop = typeof(Arguments).GetProperty(propertyName);
        if(prop != null)
        {
            object[] dbFieldAtts = prop.GetCustomAttributes(typeof(ArgumentAttribute), true);
            if(dbFieldAtts.Length > 0)
            {
                return ((ArgumentAttribute)dbFieldAtts[0]).AssignmentDelimiter;
            }
        }
    }
    return null;
}

要使用它,只需:

string delimiter = GetCommandLineDelimiter(() => myObject.Name);

这将在属性Name上获得AssignmentDelimiter的属性值,即“=”。

答案 2 :(得分:0)

这很有效。我正在使用反射来查看 所有类型的所有属性,从而对自定义属性的引用进行延迟初始化。

public class MycustomAttribAttribute : Attribute
{
    public MycustomAttribAttribute(string name)
    {
        this.Name=name;
    }
    public string Name { get; private set; }
}
class A
{
    public A() { MyProp=new B(); }
    [MycustomAttrib(name: "OK")]
    public B MyProp { get; set; }
}


class B
{
    private static Lazy<MycustomAttribAttribute> att = new Lazy<MycustomAttribAttribute>(() =>
    {
        var types = System.Reflection.Assembly.GetExecutingAssembly().DefinedTypes;

        foreach(var item in types)
        {
            foreach(var prop in item.DeclaredProperties)
            {
                var attr = prop.GetCustomAttributes(typeof(MycustomAttribAttribute), false);
                if(attr.Length>0)
                {
                    return attr[0] as MycustomAttribAttribute;
                }
            }
        }
        return null;
    });
    public string MyProp2
    {
        get
        {
            return att.Value.Name;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Finds the attribute reference and returns "OK"
        string name = (new A()).MyProp.MyProp2;
        // Uses the stored attribute reference to return "OK"
        string name2 = (new A()).MyProp.MyProp2;
    }
}