我正在为我的工作开发一个WCF服务应用程序,我将XML转换为PRX。我遇到了一个重大障碍。这是我的代码:
public string ConvertXMLtoPRX(string theXml) //method to convert the incoming xml file to prx format
{
dynamic aXml = XDocument.Parse(theXml); //parse the XML that has been passed into the method
var mProposalMstr = aXml.Root.Element("ProposalMstr");
if (mProposalMstr == null) //check to see if the root element in the incoming XML is present
throw new Exception("Cannot be converted to PRX - element ProposalMstr not found."); //exception to be thrown if the root element is not present
System.Text.StringBuilder tempPrxString = new System.Text.StringBuilder(); //new StringBuilder object to take in incoming text from the xml file
tempPrxString.Append("StartApp"); //First part of the PRX file
tempPrxString.Append(System.Environment.NewLine);
foreach (XElement thisElem in aXml.Elements) //loop through each element in the XML file
tempPrxString.AppendLine("Field|" + thisElem.Name + "|" + thisElem.Value); //builds upon the PRX string for each node in the XML file
tempPrxString.AppendLine("EndRecord|"); //end of the PRX string
return tempPrxString.ToString(); //return the prx string
}
当它到达foreach循环时,它会遇到一个运行时错误,说明"名称' Elements'绑定到一个方法,不能像属性一样使用。"
我一直在寻找,无法找到解决方法。有没有人有什么建议?提前感谢您的帮助。
答案 0 :(得分:1)
这是因为aXml
是XDocument
。如果您查看文档,您将看到XDocument.Elements
继承自XContainer.Elements
,并且结果证明它是一个不接受任何参数的方法。 要调用不接受参数的方法,您仍然需要指定一个空参数列表(括号):
foreach (XElement thisElem in aXml.Elements());
dynamic
您可能想知道为什么这会在运行时而不是在编译时抛出错误。 dynamic
keyword告诉C#编译器它不能对修改后的表达式或变量执行类型检查。相反,将在运行时执行类型检查和解析。当您无法提前知道类型但仍想使用“普通”查看语法与其进行交互时,这非常有用。
也许您无法预测方法返回的类型。例如,它的签名表示返回object
但您知道该对象将具有具有特定名称的属性。如果您发现使一个普通的旧数据类过多工作并且只想返回匿名类型,则此模式可能有意义:
static object doSomething()
{
// Even though it’s a lie…
return new { IsFoodTasty = true, FoodType = "Angelfood Cake", };
}
public static void Main()
{
dynamic foodInfo = doSomething();
Console.WriteLine(foodInfo.IsFoodTasty ? "Food {0} tastes good." : "Food {0} tastes bad.", foodInfo.FoodType);
}
dynamic
的另一个用途是为ExpandoObject
或DynamicObject
提供更漂亮的访问权限。如,
public static void Main()
{
// I am building something like an ASP.NET MVC ViewBag…
// Though, there are myriad reasons why you should prefer
// typed views ;-).
dynamic bag = new ExpandoObject();
bag.Name = "Joe";
bag.RandomThing = "Ridiculousness.";
DoSomething(bag);
}
static void DoSomething(dynamic bag)
{
Console.WriteLine("Hi, {0}.", bag.Name);
}
dyanmic
但是,在您的情况下,您和C#编译器可以很容易地猜出XDocument.Parse(string)
的类型是什么,即XDocument
。你有两个更好的选择。通过编写XDocument.Parse(string)
告诉C#编译器您希望XDocument
返回XDocument aXml = XDocument.Parse(theXml);
,或者让C#编译器通过编写var aXml = XDocument.Parse(theXml);
来为您做推断。如果使用var
,编译器将自动将aXml
的编译时类型设置为XDocument
。关于你是使用var
还是XDocument
的问题,你现在应该在编译时而不是运行时出现这个错误:
1>c:\users\ohnob\documents\visual studio 2015\Projects\ConsoleApplication4\ConsoleApplication4\Program.cs(28,39,28,52): error CS0446: Foreach cannot operate on a 'method group'. Did you intend to invoke the 'method group'?
耶!编译器已捕获您的错误,您已从一个令人困惑的运行时崩溃中逃脱!现在,您可以添加缺少的()
并尝试再次编译...
一般情况下,如果可以,您应该避免使用dynamic
关键字。 C#具有非常强大的功能,可以帮助您使用静态类型。例如,var
存在,存在泛型支持,存在匿名类型支持,等等。将dynamic
或类型转换放入代码意味着检查C#编译器通常执行的类型将延迟到运行时。这样可以更容易编写编译良好但在运行时无法预测的代码。它甚至对性能有影响,因此即使dynamic
使特定的代码块更容易阅读,它也可能不适合紧密循环。