C# - 如何创建可更新的枚举器?

时间:2011-07-30 13:20:55

标签: c# object pass-by-reference enumerator

我对C#有点新手(来自PHP)我有点震惊,通过循环遍历列表我无法传递对该变量的引用,即以下代码无效:

foreach (ref string var in arr) {
    var = "new value";
}

我研究了一下I found a suggestion to create a "updatable enumerator",但我无法弄清楚我应该怎么做。我按照一个例子尝试为IEnumerator.Current方法和我的自定义枚举器(PeopleEnum.Current)添加一个用于Current的setter,但是,说实话,这是盲目的猜测并且不起作用。我将整个代码粘贴到pastebin上,因为这里粘贴很长 - custom enumerator attempt。在此代码中,尝试通过

访问当前元素
badClass baddie = new badClass(ref tmp.Current);

导致预期的错误“属性或索引器可能不会作为out或ref参数传递”

我最终打算做的是这样的事情 - 遍历一个对象列表,为每个对象生成一个按钮,并为该按钮添加一个onclick事件,该事件将打开一个新表单,传递参考对于该对象,以便可以使用该新表单编辑其内容。我做了所有这些,但传递对象作为参考,而不是只读数据,正在杀死我。我会感谢任何答案,我可以阅读有关可更新的枚举器或想法的链接。

3 个答案:

答案 0 :(得分:2)

首先 - 不要责怪你 - 我会说:如果你学习一门新语言,学习新语言吧!并且不要尝试使用C#开发PHP。如果计算机语言都是相同的,我们就不会有这么多。 ; - )

我没有确切地看到你的例子与你想要做的实际工作有什么关系,但是你可能首先要了解事件,代理和LINQ。可能有这样的帮助:

foreach (Obj obj in yourBaseObjects) {
    Obj localObj = obj; // See Dans comment!!!
    Button button = new Button(); // however you create your buttons
    button.Click += {
         // do something with obj
         Console.WriteLine(localObj);
    }
}

是的,这适用于C#,每个事件处理程序都将使用正确的对象。如果它不符合您的需求,您必须提供更多详细信息。

答案 1 :(得分:1)

为什么使用foreach循环。用于循环。我不知道确切的代码/语法,但有类似的东西:

int sizeOfArray=objectArray.size();
for(int i=0;i<sizeOfArray;i++)
{
    obj=objectArray[i];
    // use obj whatever you wany
}

答案 2 :(得分:0)

听起来你并没有试图传递对象的引用(对象已经是引用类型),而是引用了对象在数组中的位置,对吗?由于管理内存和引用的方式,后者在.NET中不可能直接实现。你可以使用包装类来完成类似的事情(没有错误处理,但这是基本的想法):

public sealed class ListReference<T>
{
    private readonly IList<T> _list;
    private readonly int _index;

    public ListReference(IList<T> list, int index)
    {
        _list = list;
        _index = index;
    }

    public T Value
    {
        get { return _list[_index]; }
        set { _list[_index] = value; }
    }
}

现在,您可以构建它并将其传递,同时传递对数组的多个引用所带来的所有相关复杂性风险。如果可能的话,最好改变设计以避免这种情况,但是有可能完成你所追求的目标。