我想修改对象中包含的一些字符串,比如说数组,或者修改XDocument(XText)XNode.Value中的节点。
我想从这些对象中收集字符串的子集并对其进行修改,但我不知道它们来自哪种对象类型。
换句话说,假设我有这样的对象:
List<string> fruits = new List<string>() {"apple", "banana", "cantelope"};
XDocument _xmlObject;
我希望能够将原始集合中的值子集添加到新列表中,如下所示:
List<ref string> myStrings1 = new List<ref string>();
myStrings1.Add(ref fruits[1]);
myStrings1.Add(ref fruits[2]);
List<ref string> myStrings2 = new List<ref string>();
IEnumerable<XNode> xTextNodes = getTargetTextNodes(targetPath); //some function returns a series of XNodes in the XDocument
foreach (XNode node in xTextNodes)
{
myStrings2.Add(((XText)node).Value);
}
然后使用如下通用方法更改值:
public void Modify(List<ref string> mystrings){
foreach (ref string item in mystrings)
{
item = "new string";
}
}
这样我就可以传递该方法的任何字符串集合,并修改原始对象中的字符串,而不必处理原始对象本身。
static void Main(string[] args)
{
Modify(myStrings1);
Modify(myStrings2);
}
这里的重要部分是mystrings
集合。这可能很特别。但我需要能够使用各种不同类型的字符串和字符串集合作为原始源数据进入该集合。
当然,上面的代码不起作用,也没有尝试过任何变化。这在c#中是否可行?
答案 0 :(得分:1)
你想要的是C#... ,但前提是你可以fix每个可能的字符串来源。这将允许你使用指向原始字符串的指针。但是,在整个应用程序的内存管理和unsafe代码方面,成本很高。
我鼓励你为此寻求不同的方向。
根据您的修改,您似乎始终使用整个集合,并始终立即修改整个集合。此外,这可能在一开始就不是字符串集合。我不认为您能够获得您想要的确切结果,因为您正在使用的基本XDocument类型。但探索的一个可能方向可能如下:
public IEnumerable<string> Modify(IEnumerable<string> items)
{
foreach(string item in items)
{
yield return "blah";
}
}
您可以使用projection从任何集合类型中获取字符串,然后返回修改后的文本:
fruits = Modify(fruits).ToList();
var nodes = Modify( xTextNodes.Select(n => (XText)n.Value));
一旦您了解了如何进行投影,您可能会发现现有的.Select()
方法已经完成了您所需的一切。
我真正建议的是,不是使用整个集合,而是考虑一次只使用一条记录。创建所有数据源都能理解的公共对象类型。从每个数据源创建一个投影到公共对象类型。循环遍历投影中的每个对象并进行调整。然后将另一个投影返回到原始记录类型。 这不是原始收藏品。它将是一个新集合。将新集合写回磁盘。
适当使用,与原始方法相比,它还具有更高性能的潜力。这是因为使用这些linq投影一次使用一条记录打开了流式传输数据的大门,这样一次只能将一条当前记录保存在内存中。您可以打开原始流和输出流,然后以尽可能快的速度写入输出。
答案 1 :(得分:0)
实现这一目标的最简单方法是在方法之外进行循环。这允许您通过引用传递字符串,这将使用新引用替换现有引用(不要忘记字符串是不可变的)。
这样的例子:
void Main()
{
string[] arr = new[] {"lala", "lolo"};
arr.Dump();
for(var i = 0; i < arr.Length; i++)
{
ModifyStrings(ref arr[i]);
}
arr.Dump();
}
public void ModifyStrings(ref string item)
{
item = "blah";
}