How to store reference to Class' property and access an instance's property by that? [closed]

一曲冷凌霜 提交于 2019-12-26 08:46:34

问题


How do I keep some sort of link to a class' property and then use that to access an instance's property? Thing is there are no class instances where the link is created. The idea is to remember the property before any instances can be accessed.

Here's an example:

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
}

Is there a way to do something like this in C#?


回答1:


It looks like you're looking for Reflection

Example:

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);

You still need a reference to set/get values, but this seems about what you're wanting.




回答2:


If a property is a reference type - all you need is to keep a reference to the instance. Then you can change/modify public properties/fields (or call methods) of that instance.

If a property is a value type or if you need to change the reference itself (make it point to a new instance) - the only thing that is remotely close to what you are describing involves

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

and

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

where you still need the reference to the instance whose property you want to get/set.




回答3:


You can write a property wrapper class that uses Reflection like so:

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);
        }
    }
}

And then you can use it like this:

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();
    }
}

[Edit] I was compelled to return to this to post a way of doing it without reflection:

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();
    }
}



回答4:


Not quite sure what you are asking here, but I'll give it a shot:

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);
    }
}


来源:https://stackoverflow.com/questions/17045635/how-to-store-reference-to-class-property-and-access-an-instances-property-by-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!