我有一个C#类,它对传递给它的一个公共方法的XML进行了一些解析。我们的想法是,该方法从XML中提取信息,创建对象并在公共属性中设置它们的集合......
public class XmlParser {
public List<Customer> Customers { get; set; }
public void ProcessXml(string xml) {
XElement data = XElement.Parse(xml);
CreateEntities(Customers, data);
// do other stuff...
}
}
这样,我们可以在调用代码中做这样的事情......
XmlParser xp = new XmlParser();
xp.ProcessXml(xml);
// do something with xp.Customers
我正在尝试在解析器类中编写一个私有泛型方法,它将由ProcessXml()方法使用,并保存我一遍又一遍地编写样板代码。此方法的开头看起来像这样(为清晰起见,其他参数错过了)......
private void CreateEntities<T>(List<T> collection, XElement data) {
if (collection == null) {
collection = new List<T>();
}
// process the XElement passed in, and add objects to the collection
}
我试图像这样使用它......
CreateEntities(Customers, data);
...其他参数允许编译器知道泛型类型,并允许该方法知道要创建的实体等。
但是,我遇到的问题是,虽然方法本身工作正常,并且正确填充了集合变量,但公共Customers属性仍然为null。
我认为传递引用类型,例如List&lt;&gt;一个方法允许方法修改类型,并在方法之外看到那些变化,比如this SO post中的递归答案(我知道这是一个字典,但我原以为这个原则会是一样的。)
我的方法如何将集合设置为新的List&lt;&gt;,但Customers(同一个对象)仍然为空?
更新:叹息,我应该学会阅读错误消息!
在我发布我的问题之前,我曾尝试通过ref传递集合,它给了我编译器错误。在继续计划B之前,我显然没有对这些消息给予足够的重视。
在阅读了这里的回复之后,我再次尝试了ref,并发现编译器错误是因为我试图通过ref传递公共属性,这是不允许的。我将属性从一个自动更改为一个带有支持字段,通过ref传递了支持字段,一切正常!
答案 0 :(得分:3)
我认为传递引用类型,例如List&lt;&gt;方法允许方法修改类型,并在方法
之外看到这些更改
您对通过引用传递参数(使用ref
修饰符)以及按值传递引用感到困惑。
当您将引用类型的值(例如List<Customer>
)传递给某个方法时,默认情况下仍然按值传递该参数。您可以更改变量值引用的对象的内容,但是您无法更改所引用的原始参数的对象,这就是您要执行的操作。
想想这样......如果我把一张纸和家里的地址交给某人,那么他们可以做两件事:
我将能够看到第一个动作的结果 - 它正在改变房子本身的一些东西。我不会能够看到第二个动作的结果,因为它只是改变纸上的内容......这只是什么的副本< em>我知道是我的家庭住址。
有关详细信息,请参阅my article on parameter passing in C#。
要解决您的问题,我只需将您的CreateEntities
方法更改为返回列表,而不是接受一个:
private List<T> CreateEntities<T>(XElement data)
{
var list = new List<T>();
// Populate the list...
return list;
}
如果调用者想要将这些添加到现有列表中,他们可以轻松地这样做。
答案 1 :(得分:2)
我认为您使用 ref 错过了传递引用类型。有关详细信息ref (C# Reference)