名称绑定到方法,不能像属性一样使用

时间:2014-05-05 13:33:13

标签: c# xml wcf service foreach

我正在为我的工作开发一个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'绑定到一个方法,不能像属性一样使用。"

我一直在寻找,无法找到解决方法。有没有人有什么建议?提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这是因为aXmlXDocument。如果您查看文档,您将看到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的另一个用途是为ExpandoObjectDynamicObject提供更漂亮的访问权限。如,

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使特定的代码块更容易阅读,它也可能不适合紧密循环。