Alternative to using ref in foreach?

情到浓时终转凉″ 提交于 2019-12-04 03:12:27

问题


I have a modifying method with a signature like

private bool Modify(ref MyClass obj);

that will make modifications to obj and indicate succes with it's return value. Modify is not reassigning the reference (I know that this wouldn't work), just modifying instance fields, so I want to use it to do something like the following:

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

I am running into a problem compiling as obj is "not being passed with the ref keyword". However, if I put the ref keyword in like so:

bool success = Modify(ref obj);

I get "cannot use obj as a ref/out because it is a 'foreach iteration variable". I understand that foreach uses an immutable iterator and that's why this doesn't work.

My question is what is the easiest alternative to make something like this work?

I have tried using

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

but they I get "a property or indexer may not be passed as an out of ref parameter".

Thanks your help.


回答1:


You state

Modify is not reassigning the reference

Therefore, there is no reason the Modify(ref MyClass) function needs to pass argument by ref.

You should be able to do the same "modifications", whatever that is (please clarify that) by passing the object reference by value, i.e. removing the ref keyword.

So, the fix here should be changing your Modify function signature from Modify(ref MyClass) to Modify(MyClass)




回答2:


Any type within C# is passed actually by value. When you however pass an instance of a class to a method what is actually passed is not the instance itself but a reference to it which itself is passed by value. So effectivly you're passing instances of a class as reference - which is why you call them reference-types.

This means that you modify the instance referenced by that reference-value in your method, no need to use the ref-keyword.

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

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

If you'd really pass the reference by reference you'd re-assign the obj on every iteration within your loop which isn't allowed within a foreach-block.

On the other side you could also use a classic for-loop. However you'd need a temporary variable to store the outcome of your method:

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



回答3:


It is solved by using LINQ.

My Code:

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


来源:https://stackoverflow.com/questions/45380539/alternative-to-using-ref-in-foreach

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!