如何存储一个属性的引用

3
有没有一种方法可以将一个属性的引用存储到一个变量中,使我能够像访问该对象的属性一样访问它,就像这样:
var ReferenceVariable = Object.Property;
ReferenceVariable = "SOMETHING";
If (Object.Property == "SOMETHING")
    //It worked! Yaay!

如果是这样,我该怎么做呢?
编辑:为了更清晰一些,这就是正在发生的事情:
private void UpdateColor(){
    if (radioButton1.Checked){
        Object.Color1 = Color.Red
    }
    if (radioButton2.Checked){
        Object.Color2 = Color.Blue
    }
    .
    .
    .
    if (radioButtonN.Checked){
        Object.ColorN = Color.ColorN
    }
}

这非常不理想。理想情况下,问题应该在单选按钮更改时触发的函数中处理,这样它会变成类似于...

private void RadioButton_CheckChanged(object sender, eventargs e){
    //Something is done here to tell the program that we are interested in Object.Color...Whatever
}

private void UpdateColor(){
    //Now we know what color we're looking at, we can just do it in one step rather than looking at a thousand (I exaggerate of course) radio buttons checked states.
}

我希望这能帮助你更好地帮助我...


抓住一个拥有属性的东西,简单来说就是对象。你的使用场景是什么?虽然在C#中无法实现你想要的具体内容,但这并不意味着我们不能帮助你完成某些任务。 - Anthony Pegram
我有一堆单选按钮,基本上是说“这是我想要调整的对象的属性”。当我选中其中一个时,我希望该属性被存储以便函数直接访问,而不需要通过大量级联的if语句检查每个单选按钮是否被选中,然后通过修改与所选按钮相关的属性来响应。 - Will
好的。那么也许可以通过点击按钮来激活某个知道要操作哪个属性的东西。例如,它可以是符合通用接口或委托(Func、Action)的类实例。不要持有该属性,而是持有一个“东西”,它知道如何操作和操作哪个属性。在您的问题中添加一些代码,以便描述您打算使用所选属性做什么,也许有人可以帮助制定适当的代码解决方案。(Thing 是一个技术术语。) - Anthony Pegram
为什么不为每个按钮编写一个处理程序呢? - user1914530
因为单击单选按钮并不会改变对象的属性。表单上还有其他组件可以实现这一点,如滑动条和数字选择框。但由于我们在处理的属性类型只有.Color,所以没有必要为每个属性创建一组控件。 - Will
3个回答

2
假设我正确理解您的需求,您可以使用一个Action<>委托来设置您的属性。以下示例代码(在Windows Forms应用程序中)使用一个Dictionary来存储每个单选按钮的委托。所有单选按钮共享同一个事件处理程序,该处理程序从字典中检索委托,并将其设置为colorSetter变量中的当前委托。我只是在表单上使用一些按钮来改变颜色,根据选中的单选按钮,适当的颜色属性将被更改。
public partial class Form1 : Form {
    private readonly ColorPropertyObject cpo = new ColorPropertyObject();
    private Action<Color> colorSetter;

    private readonly Dictionary<RadioButton, Action<Color>> setterDictionary =
        new Dictionary<RadioButton, Action<Color>>();


    public Form1() {
        InitializeComponent();
        setterDictionary.Add(radioButton1, c => cpo.Color1 = c);
        setterDictionary.Add(radioButton2, c => cpo.Color2 = c);
        setterDictionary.Add(radioButton3, c => cpo.Color3 = c);
    }


    private void radioButton1_CheckedChanged(object sender, EventArgs e) {
        colorSetter = setterDictionary[(RadioButton)sender];
    }


    private void button1_Click(object sender, EventArgs e) {
        colorSetter(Color.Blue);
    }


    private void button2_Click(object sender, EventArgs e) {
        colorSetter(Color.Black);
    }


    private void button3_Click(object sender, EventArgs e) {
        colorSetter(Color.Red);
    }


    private void button4_Click(object sender, EventArgs e) {
        Console.WriteLine(cpo.Color1 + " - " + cpo.Color2 + " - " + cpo.Color3);
    }
}

public class ColorPropertyObject {
    public Color Color1 { get; set; }
    public Color Color2 { get; set; }
    public Color Color3 { get; set; }
}

我要预先将这标记为正确,因为我相信它会工作。 它甚至会完全消除UpdateColor函数的需求,因为每次用户单击单选按钮时都将设置该操作。 非常感谢。同样感谢您@Anthony Pegram - Will

0
    static void Main(string[] args)
    {
        var props = typeof(MyClass).GetProperties();
        foreach (var propertyInfo in props)
        {
            if (propertyInfo.Name == "property")
            {
                var prop = propertyInfo;
            }
        }
    }
}

class MyClass
{
    public static string property { get; set; } 
}

这并没有对解决问题做出任何贡献。 - Anthony Pegram

0

针对所提出的问题给出快速回答:

有没有一种方法可以将属性的引用存储到变量中,以便我可以像访问该对象的属性一样访问它?

C#不支持传递和保留对属性的引用。某些语言可能支持这一点,但C#不支持。您当然可以引用与属性持有的相同的对象,并对其持有的状态进行任何受支持的变异,但是如果想稍后完全覆盖属性值(基本上:重新分配,如您的示例所示),则需要保留对拥有属性的对象的引用。


现在也许可以帮助解决你的问题。

你可以考虑根据用户输入改变策略的想法。如果你只是简单地改变颜色,那么这种模式可能不会给你带来太多好处。但是,如果你要改变颜色、编写一些自定义文本,并向毫无防备的橡胶蚂蚁发射激光,那么更高程度的复杂性可以通过包含这些策略的类来封装,你可以根据选择简单地切换它们(或者激活其中一个)。

这些策略可以表示为符合给定接口的类,也可以表示为委托。你可以根据自己的项目决定哪种方式最合适。

需要明确的是,在你的单选按钮事件处理程序中,你要确定你希望采用哪种策略。这个策略知道如何处理你的对象。

myStrategy = redStrategy; // Func, Action, class instance as applicable

如果您的策略只是表达为Action<...>,那么它可能类似于:
Action redStrategy = () => 
{
    obj.Color1 = Color.Red;
    obj.Text1 = "Red selected";
    obj.BurnRedRubberAnts();
}

在你的更新方法中,你只需使用任何适用的参数(上面没有定义)调用预先确定的策略并让它执行。
myStrategy(/* args */)

你可以修改它来接受参数,返回值(使用Func而不是Action),或者将其完全开发为可测试的类。或者所有这些都可能过度设计了你想要做的事情,在这种情况下,你可以使用你试图避免的那个switch语句。

如果你对这样的技术感兴趣,我建议阅读策略模式命令模式也似乎正在崭露头角。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接