-2

如何保持某种指向类属性的链接,然后使用它来访问实例的属性?问题是没有创建链接的类实例。这个想法是在可以访问任何实例之前记住该属性。

这是一个例子:

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

4 回答 4

3

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

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();
    }
}
于 2013-06-11T13:59:28.820 回答
2

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

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

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

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

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

于 2013-06-11T13:51:20.837 回答
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值的引用,但这似乎是您想要的。

于 2013-06-11T13:55:17.880 回答
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);
    }
}
于 2013-06-11T14:03:20.277 回答