【问题标题】:Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement只有 assignment、call、increment、decrement、await 和 new 对象表达式可以用作语句
【发布时间】:2013-07-23 02:50:21
【问题描述】:

我有这个 foreach 部分,我试图在“result = string.Format”之后添加一行,但我收到以下错误“只能使用赋值、调用、递增、递减、等待和新对象表达式作为一个声明“有人可以告诉我我做错了什么。

foreach (DataRow record in table.Rows)
{
    string key = record["Code"] + "_" + record["Description"];
    int row = (int)rownum[key];

    string date = formatDate(record["ApptDate"].ToString(), "_");

    string result = string.Empty;
    if (record["Dosage"].ToString() != string.Empty)
        result = string.Format("{0}/{1}", test.SharedLib.Application.RemoveTrailingZeroes(record["Dosage"].ToString()), 
                                          test.SharedLib.Application.RemoveTrailingZeroes(record["Units"].ToString()));
    if (record["Dosage"].ToString() != string.Empty)
        result.StartsWith("/") && result.EndsWith("/") ? result.Replace("/", string.Empty) : result;
    else if (record["Units"].ToString() != string.Empty)
        result = record["Units"].ToString();

    dataTable.Rows[row]["ApptDate" + date] = result;
}

【问题讨论】:

  • 为什么你的 if 块周围没有 {}
  • result = result.StartsWith("/") && result.EndsWith("/") ? result.Replace("/", string.Empty) : result;

标签: c# c#-4.0


【解决方案1】:
if (record["Dosage"].ToString() != string.Empty)
    result.StartsWith("/") && result.EndsWith("/") ? result.Replace("/", string.Empty) : result;

第二行不是语句,是表达式。并非所有表达式都可以是 C# 中的语句,因此这是语法错误。

大概你打算将这个结果分配给result

if (record["Dosage"].ToString() != string.Empty)
    result = (result.StartsWith("/") && result.EndsWith("/")) ? result.Replace("/", string.Empty) : result;

此外,您应该考虑用大括号 ({}) 将 if / else 块的主体括起来。没有大括号,这些块的嵌套方式不直观,并且会妨碍将来的维护。 (例如,你能分辨出else if 块属于哪个if 块吗?继承这个项目的下一个人不仅能够分辨出区别,而且能够理解嵌套的意图?让它明确!)

【讨论】:

  • 我认为,在这种情况下,缺少花括号绝对是个人喜好问题。虽然我同意没有它们的代码目前看起来很混乱。另一种方法可能是将一些较长的行提取到具有更直观名称的私有方法中,这些名称描述了正在执行的逻辑。这样代码会读起来更简洁,不需要用花括号对长语句进行分组。
  • @David 虽然我一般同意个人偏好,但这不是一种情况。没有大括号的代码在维护时更容易损坏,尤其是正是问题中的那种代码。根据问题,他插入了中间的if 块。他的意思是让它成为第一个if 块的一部分吗?他是否意识到else 块现在属于新的if 块而不是第一个块?大括号有助于准确消除这类问题的歧义。所有这些都以包含最后一个} 的额外行为代价。这是一个很好的权衡。
【解决方案2】:

您必须对表达式的结果做一些事情(例如将其分配给结果?!)

要了解更多信息,您应该真正格式化并告诉我们更多有关您的代码的信息...所以用户不是您的个人编译器/调试器;-)

【讨论】:

  • 我也没有看到任何丢失的大括号,否则会需要。
  • 我也没有看到任何缺失的大括号。 OP 并不 需要 它们,但是在这样的条件句中使用大括号将是一件非常好的事情,因为完全不清楚他将它们嵌套的方式是否是他希望它们嵌套的方式。
  • @D.R.代码已编辑,但没有添加或删除分号。唯一的编辑是空白。
  • 哎呀,很抱歉造成混乱,你是对的。由于不幸的格式,我没有看到第二个 if 在 else if 之前。
  • 我删除了答案中令人困惑的部分,再次抱歉。
【解决方案3】:
result.StartsWith("/") && result.EndsWith("/") ? result.Replace("/", string.Empty) : result;

这一行对三元运算符的结果没有任何作用。我假设您想将其分配给结果

【讨论】:

    【解决方案4】:

    在我的情况下,我得到如下错误

    Message=(1,1): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
      Source=Microsoft.CodeAnalysis.Scripting
    

    当我调用以下方法时。

    private static async Task TrialUsingRoslynScriptingApi1()
    {
        var scriptOptions = ScriptOptions.Default;
    
        var assemblies = AppDomain.CurrentDomain.GetAssemblies(); // .SingleOrDefault(assembly => assembly.GetName().Name == "MyAssembly");
    
        foreach (Assembly assembly in assemblies)
            scriptOptions = scriptOptions.AddReferences(assembly);
    
    
        scriptOptions = scriptOptions.AddImports("System");
        scriptOptions = scriptOptions.AddImports("System.Collections.Generic");
       
        var codeString = @"iList =>
        {
            var finalResult = 0;
    
            foreach (var i in iList)
                finalResult = finalResult + i;
    
            return finalResult;
        };
        return arithmeticSum;";
    
        Func<List<int>, int> arithmeticSum = await CSharpScript.EvaluateAsync<Func<List<int>, int>>(codeString, scriptOptions);
            
        var iListOfNumbers = new List<int>() { 1, 2, 3, 4, 5 };
    
        Console.WriteLine(arithmeticSum.Invoke(iListOfNumbers));
        Console.WriteLine(arithmeticSum(iListOfNumbers));
    
    }
    

    为了缓解这种情况,我将 codeString 更改为以下内容。注意最后的return语句和开头的赋值。

    var codeString = @"Func<List<int>, int> arithmeticSum = iList =>
        {
            var finalResult = 0;
    
            foreach (var i in iList)
                finalResult = finalResult + i;
    
            return finalResult;
        };
        return arithmeticSum;";
    

    请注意,这不是一个常规用例,我正在尝试使用 roslyn(.NET Compiler platform) 即时编译一段代码。

    要运行此示例,请执行以下操作。

    1. 在 .net core 上创建控制台应用
    2. 添加Microsoft.CodeAnalysis.CSharp.Scripting nuget包。
    3. 根据需要添加以下部分或全部 using 语句。

    使用语句

    using Microsoft.CodeAnalysis.CSharp.Scripting;
    using Microsoft.CodeAnalysis.Scripting;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Reflection;
    using System.Threading.Tasks;
    
    1. 最后调用方法如下。

    Program.cs文件中的Main方法如下。

    static async Task Main(string[] args)
    {
        Console.WriteLine("Hello World! A demo of string to lambda with Roslyn");
    
        await TrialUsingRoslynScriptingApi1();
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-07
      • 2013-02-18
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多