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

发布于 2024-11-27 06:08:05 字数 811 浏览 1 评论 0原文

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

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

我研究了一下并且我找到了创建“可更新的枚举器” 但我不知道我到底应该如何做到这一点。我按照一个示例,尝试为 IEnumerator.Current 方法和我的自定义枚举器 (PeopleEnum.Current) 添加 Current 的设置器,但是,说实话,这是盲目猜测并且不起作用。我将整个代码粘贴到pastebin,因为粘贴到这里很长 - 自定义枚举器尝试。在此代码中,尝试访问当前元素会导致

badClass baddie = new badClass(ref tmp.Current);

预期错误“属性或索引器可能无法作为 out 或 ref 参数传递”

我最终想要做的是这样的 - 迭代对象列表,为每个对象生成一个按钮,并为该按钮添加一个 onclick 事件,该事件将打开一个新表单,传递该对象的引用,以便可以在该新表单中编辑其内容。我做了所有这些,但是将对象作为引用而不是只读数据传递,这简直要了我的命。我将不胜感激任何答案,链接,我可以阅读有关可更新的枚举器或想法。

I'm a bit new to C# (coming from PHP) and I was a bit shocked that, by looping through a list I can't pass a reference to that varialbe, i.e. the following code is not valid:

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

I researched a bit and I found a suggestion to create a "updatable enumerator" but I can't figure out how exactly I should do that. I followed an example and tried to add a setter for the Current for both the IEnumerator.Current method and my custom enumerator (PeopleEnum.Current), but, to be honest, that was blind guessing and didn't work. I'm pasting the whole code at pastebin, as it's quite long to paste here - custom enumerator attempt. In this code, trying to access the current element by

badClass baddie = new badClass(ref tmp.Current);

results in an expected error that "A property or indexer may not be passed as an out or ref parameter"

What I'm aiming to do in the end is something like this - iterate through a list of objects, generate a button for each of them and add an onclick event for that button which will open a new form, passing the reference for that object, so that its contents can be edited in that new form. I did all this, but passing the object as a reference, instead of read-only data, is killing me. I would appreciate any answers, links where I can read about updatable enumerators or ideas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦幻的味道 2024-12-04 06:08:05

首先 - 不想责怪你 - 我想说:如果你学习一门新语言,就学习新语言!并且不要尝试使用 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# 中有效,并且每个事件处理程序将使用正确的对象。如果不符合您的需求,您必须提供更多详细信息。

First of all - without wanting to blame you - I would say: If you learn a new language, learn the new language! And don't try to develop PHP using C#. If computer languages would all be the same, we would not have so much of them. ;-)

I don't see exactly how your example is related to the actual job you want to do, but you shoudl probably learn about events, delegates and LINQ first. Might something like this help:

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

Yes, that works in C# and each event handler will be using the correct object. If it does not fit your needs, you have to provide more details.

暗喜 2024-12-04 06:08:05

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

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

Why you are using foreach loop. Use for loop. I dont know the exact code/syntax but something like that:

int sizeOfArray=objectArray.size();
for(int i=0;i<sizeOfArray;i++)
{
    obj=objectArray[i];
    // use obj whatever you wany
}
两人的回忆 2024-12-04 06:08:05

听起来您并不是试图传递对对象的引用(对象已经是引用类型),而是传递对对象在数组中的位置的引用,对吗?由于 .NET 管理内存和引用的方式,后者在 .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; }
    }
}

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

It sounds like you're not trying to pass a reference to the Object (the Object is already a reference type), but rather a reference to the Object's location in the array, correct? This latter is not directly possible in .NET, due to the way it manages memory and references. You can accomplish something like it using a wrapper class (no error handling, but this is the basic idea):

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

You can now construct this and pass it along, with all the associated complexity risks that come with passing around multiple references to an array. It would be better to change the design to avoid this, if possible, but it is possible to accomplish what you're after.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文