我有一个带有签名的修改方法,如
private bool Modify(ref MyClass obj);
将对obj
进行修改,并指出其成功的返回值。 Modify
没有重新分配引用(我知道这不会起作用),只是修改实例字段,所以我想用它来做类似以下的事情:
foreach(MyClass obj in myList)
{
bool success = Modify(obj);
// do things depending on success
}
我遇到问题正在编译obj
是"没有使用ref
关键字"传递。但是,如果我将ref关键字放入如下:
bool success = Modify(ref obj);
我得到"无法将obj
用作ref
/ out
,因为它是一个#foreach迭代变量"。我知道foreach使用了一个不可变的迭代器,这就是为什么它不起作用。
我的问题是,做这样的工作的最简单方法是什么?
我尝试过使用
foreach(int i = 0; i < myList.Count; i++)
{
bool success = Modify(ref myList[i]);
// do things depending on success
}
但我得到&#34;属性或索引器可能不会作为ref参数传递#34;。
谢谢你的帮助。
答案 0 :(得分:13)
C#中的任何类型实际上都是按值传递。然而,当您将类的实例传递给方法时,实际传递的方法不是实例本身,而是引用,它本身通过值传递 / em>的。所以有效你将类的实例作为参考传递 - 这就是你称它们为引用类型的原因。
这意味着您修改方法中该引用值引用的实例,无需使用ref
- 关键字。
foreach(var m in myList)
{
MyMethod(m);
}
MyMethod(MyClass instance)
{
instance.MyProperty = ...
}
如果您确实通过引用传递了引用,则在循环内的每次迭代中重新分配obj
,这是不允许的一个foreach
- 块。
另一方面,您也可以使用经典的for循环。但是,您需要一个临时变量来存储方法的结果:
for(int i = 0; i < myList.Length; i++)
{
var tmp = myList[i];
MyMethod(ref tmp);
myList[i] = tmp;
}
答案 1 :(得分:9)
你陈述
修改不会重新分配参考
因此,Modify(ref MyClass)
函数没有理由需要通过ref
传递参数。
您应该能够通过按值传递对象引用(即删除ref
关键字)来执行相同的修改&#34;,无论是什么(请澄清),
因此,此处的修复方法应该是将修改功能签名从Modify(ref MyClass)
更改为Modify(MyClass)
答案 2 :(得分:0)
使用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");
}
答案 3 :(得分:0)
使用临时变量绕过消息
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 = ...
}