如何存储对Class'属性的引用并通过它访问实例的属性?

时间:2013-06-11 13:41:29

标签: c# properties reference

如何保持某种类属性的链接,然后使用它来访问实例的属性?事情是没有创建链接的类实例。我们的想法是在访问任何实例之前记住该属性。

以下是一个例子:

Class A { int integer { get; set; }  }

var link = GetLink(A.integer); // implementetion of GetLink(???) is unknown

MyMethod(link);

void MyMethod(??? link)
{
    A a = new A();
    int i = GetValueByLink(a, link); // this is also undefined
}

有没有办法在C#中做这样的事情?

4 个答案:

答案 0 :(得分:2)

如果属性是引用类型 - 您只需要保留对实例的引用。然后,您可以更改/修改该实例的公共属性/字段(或调用方法)。

如果属性是值类型,或者如果您需要更改引用本身(使其指向新实例) - 唯一与您描述的内容非常接近的内容涉及

PropertyInfo property = obj.GetType().GetProperty(<property name>);

object value = property.GetValue(obj, null);
property.SetValue(obj, newValue, null);

您仍然需要对要获取/设置其属性的实例的引用。

答案 1 :(得分:2)

看起来你正在寻找Reflection

示例:

public class A
{
  int integer{get; set;}
}

PropertyInfo prop = typeof(A).GetProperty("integer");
A a = new A();
prop.GetValue(a, null);
prop.SetValue(a, 1234, null);

你仍然需要引用set/get值,但这似乎与你想要的一样。

答案 2 :(得分:1)

您可以编写一个使用Reflection的属性包装类,如下所示:

public class PropertyWrapper<T>
{
    readonly PropertyInfo property;
    readonly object obj;

    public PropertyWrapper(object obj, string propertyName)
    {
        property = obj.GetType().GetProperty(propertyName);
        this.obj = obj;
    }

    public T Value
    {
        get
        {
            return (T)property.GetValue(obj);
        }

        set
        {
            property.SetValue(obj, value);
        }
    }
}

然后你可以像这样使用它:

public class Test
{
    public string Item { get; set; }
}

class Program
{
    void run()
    {
        Test test = new Test { Item = "Initial Item" };

        Console.WriteLine(test.Item); // Prints "Initial Item"

        var wrapper = new PropertyWrapper<string>(test, "Item");

        Console.WriteLine(wrapper.Value); // Prints "Initial Item"

        wrapper.Value = "Changed Item";

        Console.WriteLine(wrapper.Value); // Prints "Changed Item"
    }

    static void Main()
    {
        new Program().run();
    }
}

[编辑]我被迫回到这里以发布一种没有反思的方式:

public class PropertyWrapper<T>
{
    readonly Action<T> set;
    readonly Func<T>   get;

    public PropertyWrapper(Func<T> get, Action<T> set)
    {
        this.get = get;
        this.set = set;
    }

    public T Value
    {
        get
        {
            return get();
        }

        set
        {
            set(value);
        }
    }
}

public class Test
{
    public string Item
    {
        get;
        set;
    }
}

class Program
{
    void run()
    {
        Test test = new Test
        {
            Item = "Initial Item"
        };

        Console.WriteLine(test.Item); // Prints "Initial Item"

        var wrapper = new PropertyWrapper<string>(() => test.Item, value => test.Item = value);

        Console.WriteLine(wrapper.Value); // Prints "Initial Item"

        wrapper.Value = "Changed Item";

        Console.WriteLine(wrapper.Value); // Prints "Changed Item"
    }

    static void Main()
    {
        new Program().run();
    }
}

答案 3 :(得分:0)

不太确定你在这里问的是什么,但我会试一试:

class Program
{
    class A
    {
        public static List<A> MyProperties = new List<A>();
        public int Id { get; set; }
        public string Value { get; set; }
    }

    static void Main(string[] args)
    {
        A a = new A() { Id = 1, Value = "Test" };
        A.MyProperties.Add(a);
        MyMethod(1);
    }

    static void MyMethod(int id)
    {
        var instance = A.MyProperties.First(link => link.Id == id);
        Console.WriteLine(instance.Value);
    }
}