繁体   English   中英

C#变量和或Form对象的引用数组

[英]C# Array of references to Variables and or Form objects

我正在尝试做的是拥有一个对变量的引用数组。 我的意思是等效于一个指向int的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是对Textbox的引用。

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

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

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

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

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

明确要求的是不可能的; 更为合适的方法(并具有实际工作的便利!)将围绕您要执行的操作设计一个类结构。

例如,如下所示:

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

然后,在您的代码中,您可以执行与此类似的操作...

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

显然,这只是一个粗略的设计,此处的类只不过是数据传输容器。 例如,可以通过使用Value属性的设置器来自动设置TextBox的值,从而使类“更智能”。 但这有望使您大致了解如何以OO方式完成此类工作。

编辑这是您的示例的外观。

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

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

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

可以使用委托人来伪造这种东西,但是我不确定这是否是您要的东西。 我也很确定您确实需要重新设计方法,但是,这是一个如何伪造它的示例...

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

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()返回了一个ValueWrapper ,这显然是在test()内部包装了一个局部变量。 然后我们显然可以更改该值并打印出来...

当然,这并不是真正发生的事情,但是可能会造成混乱!

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

我用了这个并且工作完美:

进出口。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM