在单个 LINQ 表达式中嵌入 null 测试

发布于 2024-12-09 04:43:11 字数 807 浏览 0 评论 0原文

让我们从一个简单的示例类开始:

public class Foo
{
    public DateTime Date { get; set; }
    public decimal Price { get; set; }
}

然后创建一个列表:

List<Foo> foos = new List<Foo>;

我想根据日期返回列表中一项的格式化价格或“N/A”,所以例如我可以写:

Foo foo = foos.FirstOrDefault(f => f.Date == DateTime.Today);
string s = (foo != null) ? foo.Price.ToString("0.00") : "N/A";

我会喜欢将上面两行组合起来以下内容:

string s = foos.FirstOrDefault(f => f.Date == DateTime.Today).Price.ToString("0.00") ?? "N/A";

但是,这并没有达到我想要的效果,因为 if (f => f.Date == DateTime.Today) 不返回 Foo 然后返回抛出NullReferenceException

因此,是否可以使用 LINQ 创建 1 个语句来返回格式化价格或“N/A”?

Let's start with a simple example class:

public class Foo
{
    public DateTime Date { get; set; }
    public decimal Price { get; set; }
}

Then create a list:

List<Foo> foos = new List<Foo>;

I would like to return a formatted price or "N/A" of one item in the list based on a date, so for example I could write:

Foo foo = foos.FirstOrDefault(f => f.Date == DateTime.Today);
string s = (foo != null) ? foo.Price.ToString("0.00") : "N/A";

I would like to combine the above 2 lines like the following:

string s = foos.FirstOrDefault(f => f.Date == DateTime.Today).Price.ToString("0.00") ?? "N/A";

However, this does not achieve what I want because if (f => f.Date == DateTime.Today) does not return a Foo then a NullReferenceException is thrown.

Therefore, is it possible with LINQ to create just 1 statement to either return the formatted price or "N/A"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别靠近我心 2024-12-16 04:43:11

如果先过滤然后选择,则可以使用空合并运算符 (??),如下所示:

string price = foos.Where(f => f.Date == DateTime.Today)
                   .Select(f => f.Price.ToString())
                   .FirstOrDefault() ?? "N/A";

If you filter first and then select, you can use the null coalescing operator (??) like so:

string price = foos.Where(f => f.Date == DateTime.Today)
                   .Select(f => f.Price.ToString())
                   .FirstOrDefault() ?? "N/A";
放低过去 2024-12-16 04:43:11

一种方法是在调用 ToString 之前简单地检查 FirstOrDefault 的结果是否为 null:

var todayFoo = foos.FirstOrDefault(f => f.Date == DateTime.Today);
var s = todayFoo != null ? todayFoo.Price.ToString("0.00") : "N/A";

另一种方法是为合并运算符创建一个扩展方法,该方法也接受投影委托,类似:

public static class ObjectExt
{
    public static T2 Coalesce<T1, T2>(
         this T1 obj, Func<T1, T2> projection, T2 defaultValue)
    {
        if (obj == null)
            return defaultValue;

        return projection(obj);
    }
}

然后这样调用它:

var s = foos
         .FirstOrDefault(f => f.Date == DateTime.Today)
         .Coalesce(t => t.Price.ToString("0.00"), "N/A");

One way would be to simply check if result of FirstOrDefault is null, before calling ToString:

var todayFoo = foos.FirstOrDefault(f => f.Date == DateTime.Today);
var s = todayFoo != null ? todayFoo.Price.ToString("0.00") : "N/A";

Another way would be to create an extension method for a coalescing operator which also accepts a projection delegate, something like:

public static class ObjectExt
{
    public static T2 Coalesce<T1, T2>(
         this T1 obj, Func<T1, T2> projection, T2 defaultValue)
    {
        if (obj == null)
            return defaultValue;

        return projection(obj);
    }
}

And then call it like this:

var s = foos
         .FirstOrDefault(f => f.Date == DateTime.Today)
         .Coalesce(t => t.Price.ToString("0.00"), "N/A");
瀟灑尐姊 2024-12-16 04:43:11

string s = foos.Where(f => f.Date == DateTime.Today).Select(f => f.Price.ToString("0.00")).FirstOrDefault();

string s = foos.Where(f => f.Date == DateTime.Today).Select(f => f.Price.ToString("0.00")).FirstOrDefault();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文