在 foreach 中使用 ref 的替代方案?

Alternative to using ref in foreach?

我有一个带有签名的修改方法

private bool Modify(ref MyClass obj);

这将对 obj 进行修改并用它的 return 值表示成功。 Modify 没有重新分配引用(我知道这行不通),只是修改实例字段,所以我想用它来做类似下面的事情:

foreach(MyClass obj in myList)
{
    bool success = Modify(obj);
    // do things depending on success
}

我 运行 遇到编译问题,因为 obj 是 "not being passed with the ref keyword"。但是,如果我像这样放置 ref 关键字:

bool success = Modify(ref obj);

我得到 "cannot use obj as a ref/out because it is a 'foreach iteration variable"。我知道 foreach 使用不可变迭代器,这就是它不起作用的原因。

我的问题是,要实现这样的效果,最简单的替代方法是什么?

我试过使用

foreach(int i = 0; i < myList.Count; i++)
{
    bool success = Modify(ref myList[i]);
    // do things depending on success
}

但我得到了 "a property or indexer may not be passed as an out of ref parameter"。

感谢您的帮助。

你说

Modify is not reassigning the reference

因此,Modify(ref MyClass) 函数没有理由需要通过 ref 传递参数。

你应该能够做同样的事情 "modifications",无论那是什么(请澄清)通过按值传递对象引用,即删除 ref 关键字。

所以,这里的修复应该是将您的修改函数签名从 Modify(ref MyClass) 更改为 Modify(MyClass)

C# 中的任何类型实际上都是按值传递的。当您将 class 的实例传递给方法时,实际上 传递的 不是实例本身,而是对它的 reference本身通过值 传递 。所以 有效地 你传递了一个 class 的实例作为引用——这就是你称它们为引用类型的原因。

在您的情况下,您只需 修改 方法中该引用值引用的现有实例,无需使用 ref-关键字。

foreach(var m in myList)
{
    MyMethod(m);
}

MyMethod(MyClass instance)
{
    instance.MyProperty = ...
}

如果您真的通过引用通过引用,您将在循环中的每次迭代中重新分配obj,这在循环中是不允许的foreach-块。这类似于以下内容:

foreach(var m in myList)
{
    m = new MyClass();
}

另一方面,您也可以使用 classic for 循环。但是,您需要一个临时变量来存储方法的结果:

for(int i = 0; i < myList.Length; i++)
{
    var tmp = myList[i];
    MyMethod(ref tmp);
    myList[i] = tmp;
}

使用LINQ解决

我的代码:

    private static List<string> _test = new List<string>();

    public List<string> Test { get => _test; set => _test = value; }


    static void Main(string[] args)
    {
        string numString = "abcd";

        _test.Add("ABcd");
        _test.Add("bsgd");

        string result = _test.Where(a => a.ToUpper().Equals(numString.ToUpper()) == true).FirstOrDefault();

        Console.WriteLine(result + " linq");
    }

使用临时变量绕过消息

foreach(MyClass obj in myList)
{
    MyClass objTemp = obj;
    bool success = Modify(ref objTemp);
    // do things depending on success
}

private MyMethod(ref MyClass instance)
{
    instance.MyProperty = ...
}