0

我想要做的是对变量的引用数组。我的意思是等效于指向整数的 C 指针数组(例如)。

示例:(!!不是真正的代码!!)

int a = 4;
int b = 5;
int c = 6;
List<ref int> tmp = new List<ref int>();

tmp.Add(ref a);
tmp.Add(ref b);
tmp.Add(ref c);

tmp[0] = 16;
tmp[1] = 3;
tmp[2] = 1000;

Console.Writeline(tmp[0] + " " + a); // 16 16
Console.Writeline(tmp[1] + " " + b); // 3 3
Console.Writeline(tmp[2] + " " + c); // 1000 1000

我的案例的细节:我有一个字符串列表,这些字符串将对应于字典中的键。我想我想要的是一个元组列表,其中 Type1 是对 int 或字符串的引用,而 Type2 是对文本框的引用。

我将遍历这个列表,使用字符串从字典中获取值(并对这些数据进行处理),然后将结果存储到 Type1 中。最终,我将从那些 Type1 变量引用中获取数据并将它们的数据复制到相应的 Type2 文本框。

这就是我想我想做的事情的要点。如果有人认为我的方法过于复杂,我会说我需要保留文本框,因为它们是可悲的,所以我不能只创建一个数组并遍历它。并且最好将 Type1 变量也保持分开,尽管不是很有必要。

现在,通过阅读,我认为 Func<> 看起来是最接近我想要的有用的东西,所以我尝试使用以下内容(使用 Type1,作为对象,因为它需要处理整数和字符串)

List<Tuple<string, Func<object>, Func<object>>>

但我不确定如何使用它来获取对变量的引用。

4

4 回答 4

4

What you're specifically asking for isn't possible; what would be more appropriate (and has the convenience of actually working!) would be to design a class structure around what you're trying to do.

For instance, something like this:

public class MyObject // Name it appropriately
{
    public object Value { get; set; }
    public string Key { get; set; }
    public TextBox TextBox { get; set; }
}

Then, in your code, you can do something akin to this...

Dictionary<string, object> values = ...
List<MyObject> objects = ...

foreach(var item in objects)
{
    item.Value = values[item.Key];

    // process your data

    item.TextBox = item.Value.ToString();
}

Obviously, this is just a rough design and the class here serves as little more than a data transfer container. You could make the class "smarter" by, for example, using the setter for the Value property to set the value of the TextBox automatically. But this should hopefully give you the general idea of how something like this would be done in an OO fashion.

EDIT Here's how your example would look.

MyObject a = new MyObject() { Value = 4 };
MyObject b = new MyObject() { Value = 5 };
MyObject c = new MyObject() { Value = 6 };
List<MyObject> tmp = new List<MyObject>();

tmp.Add(a);
tmp.Add(b);
tmp.Add(c);

tmp[0].Value = 16;
tmp[1].Value = 3;
tmp[2].Value = 1000;

Console.Writeline(tmp[0].Value.ToString() + " " + a.Value.ToString()); // 16 16
Console.Writeline(tmp[1].Value.ToString() + " " + b.Value.ToString()); // 3 3
Console.Writeline(tmp[2].Value.ToString() + " " + c.Value.ToString()); // 1000 1000
于 2013-06-19T12:34:10.567 回答
1

您不能使用 C# 存储引用。只能ref在调用方法时使用关键字。

可以使用指针,但您只能使用fixed表达式并在unsafe上下文中执行此操作。

使用代表可以伪造这种东西,但我不确定它是否是你要找的东西。我也相当确定您确实需要重新设计您的方法,但是,这里有一个如何伪造它的示例...

首先,编写一个“值包装器”类,如下所示:

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

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

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

        set
        {
            set(value);
        }
    }
}

然后你可以用它来改变值:

void run()
{
    int x = 0;

    var intWrapper = new ValueWrapper<int>(() => x, value => x = value);

    test(intWrapper);

    Console.WriteLine(x);  // Prints 42, which shows that x was changed.

    TextBox textBox = new TextBox {Text = ""};

    var stringWrapper = new ValueWrapper<string>(() => textBox.Text, value => textBox.Text = value);

    test(stringWrapper);

    Console.WriteLine(textBox.Text); // Prints "Changed".
}

static void test(ValueWrapper<int> wrapper)
{
    wrapper.Value = 42;
}

static void test(ValueWrapper<string> wrapper)
{
    wrapper.Value = "Changed";
}

您还可以在一种方法中创建包装器并将其传递给使用包装器更改原始包装对象中的属性的不同方法,如下所示:

void run()
{
    TextBox textBox = new TextBox {Text = ""};

    var wrapper = test1(textBox);
    test2(wrapper);
    Console.WriteLine(textBox.Text); // Prints "Changed"
}

void test2(ValueWrapper<string> wrapper)
{
    wrapper.Value = "Changed";
}

ValueWrapper<string> test1(TextBox textBox)
{
    return new ValueWrapper<string>(() => textBox.Text, value => textBox.Text = value);
}

警告:这确实会导致一些相当令人头疼的代码,例如:

void run()
{
    var intWrapper = test();
    intWrapper.Value = 42;
    Console.WriteLine(intWrapper.Value); // Works, but where is the value? It can't be the x inside test()!
}

ValueWrapper<int> test()
{
    int x = 0;
    var intWrapper = new ValueWrapper<int>(() => x, value => x = value);
    return intWrapper;
}

所以我们返回了一个显然是从 test() 内部包装了一个局部变量的ValueWrappertest()然后我们显然可以更改值并将其打印出来......

当然,这并不是真正发生的事情,但它可能会令人困惑!

于 2013-06-19T12:41:14.583 回答
0

在这种情况下,您可以使用指针,对方法使用 unsafe 关键字并设置项目不安全以允许在 c# 中使用指针,也可以将值封装在一个类中,并且在 C# 中每个类都是引用类型

于 2013-06-19T14:32:38.653 回答
0

我使用了这个并且效果很好:

exp。

public int value1 = 3;
public int value2 = 4;
public int value3 = 5;

public void Method1()
{
    int[] values = { value1, value2, value3};
    for (int i = 0; i < values.Length; i ++)
    {
        Console.WriteLine(values[i]);
    }
}
于 2018-08-09T02:33:18.663 回答