存储对字典中对象的引用

Tho*_*Hut 9 c# dictionary reference object

我一直在寻找一种方法来将各种类型的变量的引用保存到字典中,以及相应的密钥.然后我想通过其键通过字典访问它的引用来修改变量的实例.为了存储引用,我尝试使用<object>,但没有成功.字典和列表都不接受任何类似的东西Dictionary<string, ref int>.以下代码编译,但似乎只按值更新变量.任何想法或解决方法?

这是(经过测试的)代码:

class Test1
{
    IDictionary<string, object> MyDict = new Dictionary<string, object>();

    public void saveVar(string key, ref int v) //storing the ref to an int
    {
        MyDict.Add(key, v);
    }
    public void saveVar(string key, ref string s) //storing the ref to a string
    {
        MyDict.Add(key, s);
    }

    public void changeVar(string key) //changing any of them
    {
        if(MyDict.GetType() == typeof(int))
        {
            MyDict[key] = (int)MyDict[key] * 2;
        }
        if(MyDict.GetType() == typeof(string))
        {
            MyDict[key] = "Hello";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我如何调用类的方法

Test1 t1 = new Test1();
int myInt = 3;
string myString = "defaultString";

Console.WriteLine(myInt); //returns "3"
Console.WriteLine(myString); //returns "defaultString"

t1.saveVar("key1", ref myInt);
t1.saveVar("key2", ref myString);

t1.changeVar("key1");
t1.changeVar("key2");

Console.WriteLine(myInt); //should return "6"
Console.WriteLine(myString); //should return "Hello"
Run Code Online (Sandbox Code Playgroud)

Tim*_*mwi 9

我能想到的最佳解决方案是将代理存储在字典中,以便您检索和修改变量.

让我们首先声明一个包含getter和setter委托的类型:

sealed class VariableReference
{
    public Func<object> Get { get; private set; }
    public Action<object> Set { get; private set; }
    public VariableReference(Func<object> getter, Action<object> setter)
    {
        Get = getter;
        Set = setter;
    }
}
Run Code Online (Sandbox Code Playgroud)

字典将具有以下类型:

Dictionary<string, VariableReference>
Run Code Online (Sandbox Code Playgroud)

要在字典中存储变量(例如foo类型)string,您需要编写以下内容:

myDic.Add(key, new VariableReference(
    () => foo,                      // getter
    val => { foo = (string) val; }  // setter
));
Run Code Online (Sandbox Code Playgroud)

要检索变量的,您需要编写

var value = myDic[key].Get();
Run Code Online (Sandbox Code Playgroud)

要将变量的值更改newValue,您需要编写

myDic[key].Set(newValue);
Run Code Online (Sandbox Code Playgroud)

这样,您正在更改的变量确实是原始变量foo,foo可以是任何内容(局部变量,参数,对象上的字段,静态字段......甚至是属性).

把这一切放在一起,这就是这个类的Test1样子:

class Test1
{
    Dictionary<string, VariableReference> MyDict = new Dictionary<string, VariableReference>();

    public void saveVar(string key, Func<object> getter, Action<object> setter)
    {
        MyDict.Add(key, new VariableReference(getter, setter));
    }

    public void changeVar(string key) // changing any of them
    {
        if (MyDict[key].Get() is int)
        {
            MyDict[key].Set((int)MyDict[key].Get() * 2);
        }
        else if (MyDict[key].Get() is string)
        {
            MyDict[key].Set("Hello");
        }
    }
}

// ...

Test1 t1 = new Test1();
int myInt = 3;
string myString = "defaultString";

Console.WriteLine(myInt);    // prints "3"
Console.WriteLine(myString); // prints "defaultString"

t1.saveVar("key1", () => myInt, v => { myInt = (int) v; });
t1.saveVar("key2", () => myString, v => { myString = (string) v; });

t1.changeVar("key1");
t1.changeVar("key2");

Console.WriteLine(myInt);    // actually prints "6"
Console.WriteLine(myString); // actually prints "Hello"
Run Code Online (Sandbox Code Playgroud)

  • @ErikFunkenbusch:不,这不对.Lambda表达式不捕获值.他们捕获*变量*. (3认同)