【问题标题】:Total of two vallues - with one as nonzero - returning zero [duplicate]两个值的总和 - 一个为非零 - 返回零 [重复]
【发布时间】:2017-06-21 19:11:10
【问题描述】:

Action Method 之后,Total 将返回为 0,即使某些值 item1_price,, item9_price 等不是零。 View 也正确显示项目值(即 0.00 或 15.45 等),但 Total 显示为 `0。

问题:我们如何才能让 total 在这里正确工作?

public class CustomerOrdersModelView
{
    public string CustomerID { get; set; }
    public int FY { get; set; }

    public float? item1_price { get; set; }
    public float? item2_price { get; set; }
    ...
    public float? item9_price { get; set; }

    public float? Total { get; set; }
}
public async Task<IActionResult> ProductAnnualReport(string rpt)
{
    var qry = from c in _context.Customers
              join ord in _context.Orders
                on c.CustomerID equals ord.CustomerID into co
              from m in co.DefaultIfEmpty()
              select new CustomerOrdersModelView
              {
                  CustomerID = c.CustomerID,
                  FY = c.FY,
                  price = co.item1_price ?? 0,
                  price = co.item2_price ?? 0,
                  ...
                  price = co.item9_price ?? 0,

                  Total = co.item1_price ?? 0 + co.item2_price ?? 0 + ....+ co.item9_price ?? 0
              };
 }

查看:

<tr>
     <td>Item1:</td>
     <td>@Model.item1_price</td>
</tr>
<tr>
     <td>Item2:</td>
     <td>@Model.item2_price</td>
</tr>
...
<tr>
     <td>Item9:</td>
     <td>@Model.item9_price</td>
</tr>
    <tfoot>
        <tr>
            <td>TOTAL:</td>
            <td>@Model.Total</td>
        </tr>
</tfoot>
</table>

【问题讨论】:

  • 表达式中不为空的第一项为零。运算符优先级不是您认为的那样。添加括号以消除该表达式的歧义。
  • @EdPlunkett 在co.item1_price ?? 0 + co.item2_price ?? 0 + ....+ co.item9_price ?? 0 周围添加括号仍返回零。如何在控制器中测试它? - 因为当我在操作方法Total = co.item1_price ?? 0 + ...... 的最后一行放置断点时,它会将断点放置在从`new CustomerOrdersModelView{.....` 开始的整个 select 语句上
  • 我不禁注意到你没有告诉我你在哪里添加它们。不过,我可能表达得很糟糕:添加括号以表明您的意思。
  • Ed 的意思是:Total = (co.item1_price ?? 0) + (co.item2_price ?? 0) + (....) + (co.item9_price ?? 0)。现在,如果其中任何一个具有价值,那么您的 Total 将具有价值。
  • @EdPlunkett 根据您的建议,在最后一行的操作方法中,我现在有Total = (co.item1_price ?? 0 + co.item2_price ?? 0 + ....+ co.item9_price ?? 0)

标签: c# linq asp.net-core


【解决方案1】:
float? item1_price = 0;
float? item2_price = 1;
float? item3_price = 2;

float f = item1_price ?? 0 + item2_price ?? 0 + item3_price ?? 0;

f 等于 0,因为这是解析表达式的方式,由于运算符优先级和关联性:

float f = item1_price ?? ((0 + item2_price) ?? ((0 + item3_price) ?? 0));

但这就是你的意思:

float f = (item1_price ?? 0) + (item2_price ?? 0) + (item3_price ?? 0);

总是给复杂的表达式加上括号。

请参阅Section 14.2.1 of the ECMA C# Standard 以获取运算符优先级表(感谢@Silvermind 和 Eric)。优先顺序是从高到低:* 高于 +,因此 1 * 2 + 3 被解析为 (1 * 2) + 3

Primary           x.y f(x) a[x] x++ x-- 
                  new typeof checked unchecked

Unary             + - ! ~ ++x --x (T)x
Multiplicative    * / %
Additive          + -
Shift             << >>

Relational &      < > <= >= is as
type-testing

Equality          == !=
Logical           AND &
Logical           XOR ^
Logical           OR |
Conditional       AND &&
Conditional       OR ||
Null Coalescing   ??
Conditional       ?:

Assignment        = *= /= %= += -= <<= >>= 
                  &= ^= |= 

【讨论】:

  • @EdPlunkett 现在可以使用了(谢谢)。对不起,我误解了你的第一条评论
  • @nam 没有问题,我的评论本身可能使用了一些歧义。
  • 规范的相关行不是该操作是右关联的。如果它是关联的,那么括号将是((i1 ?? (0 + i2)) ?? (0 + i3)) ?? 0,这仍然是错误的。规范的相关行是运算符优先级表,表示+ 的优先级高于??。 (练习:你能不能根据??是左联想还是右联想来创建一个结果不同的程序?)
  • @EricLippert 谢谢。再一次。
猜你喜欢
  • 2018-04-08
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 2018-10-09
  • 2018-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多