有没有办法在C#中对属性执行某种null合并?

时间:2014-02-03 18:12:42

标签: c# syntax null-coalescing-operator

我不太确定如何说出这个问题,但情况如下:

说我有以下课程:

public class SampleClass
{
    public int Number { get; set; }
}

我知道你可以null合并包含的类:

SampleClass newSampleClass = possibleNullSampleClass ?? notNullSampleClass;

有没有办法在属性上执行某种null合并,所以我不必这样做:

int? num = sampleClass != null ? new int?(sampleClass.Number) : 5;

看起来像???运算符之类的东西执行此检查非常有用,所以我可以这样做:

int? num = sampleClass.Number ??? 5;

在C#中是否可以这样?

5 个答案:

答案 0 :(得分:5)

目前没有这样的运营商。但在C#6中,“安全导航”操作符将出现,您将能够编写

int number = sampleClass?.Number;

即使sampleClass等于null,此代码也不会因NullRef而失败。现在,您可以使用以下扩展方法从对象中提取值并封装null-check:

public static TResult Maybe<TSource, TResult>(
    this TSource source, Func<TSource, TResult> produceResult, Func<TResult> produceDefault)
    where TSource : class
{
    return source == null ? produceDefault() : produceResult(source);
}

并按如下方式使用:

int numberOrFive = sampleClass.Maybe(c => c.Number, () => 5);

答案 1 :(得分:3)

没有现有的运营商可以做到这一点。您已经展示了一种完全可以接受的处理问题的方法。

如果你愿意,你可以将逻辑包装在一个方法中,但我不确定这是否真的值得付出努力:

public static TResult Access<TSource, TResult>(
    TSource obj, Func<TSource, TResult> selector, TResult defaultIfNull)
    where TSource : class
{
    if (obj == null)
        return defaultIfNull;
    else
        return selector(obj);
}

SampleClass sampleClass = null;
int num = Access(sampleClass, s => s.Number, 5);

(如果你愿意,你可以考虑将其作为一种扩展方法,尽管我个人对所有类的扩展方法都很谨慎。还要考虑其他名称,例如Use。)

答案 2 :(得分:0)

我打算提议修改Servy的帖子。我认为如果它可以处理一般情况,他的方法将证明是有用的,其中在对象链的任何地方都可以存在null。

public static TResult Access<TSource, TResult>(
   TSource obj, Func<TSource, TResult> selector, TResult defaultIfNull)
   where TSource : class
{
    TResult result;
    try
    {
        result = selector(obj);
    }
    catch ( NullReferenceException)
    {
        result = defaultIfNull;
    }

    return result;

}

这样,如果您尝试访问         ZipCode = Customer.Address.ZipCode;

如果客户或地址为空,则受到保护

答案 3 :(得分:0)

你不能在C#中做到这一点。您需要明确地测试无效性:

MyWidget x ;

int? v = x == null ?  (int?)x.SomeProperty : (int?) null ;

如果您认为它有用,可以在Microsoft Connect上记录您的建议:

http://connect.microsoft.com/VisualStudio

我愿意成为他们的想法,并认为构建语言不够有用。

答案 4 :(得分:0)

你完全可以这样做:

var x = (myObject ?? DefaultObject).Field;

这就是......

var x = (myObject == null) ? myObject.Field : defaultValue;