简体   繁体   中英

What does `?.` do?

How can I express the following linq query without using

ItemSupplierName = u?.SupplierName

I keep getting a CS1525, CS1003 error message when trying to compile it on my build agent at the above line.

- CS1525 Invalid expression term '.'
- CS1003 Syntax error, ':' expected

Code below, it runs perfectly locally but fails on the build agent.

ExpandedItems = from t in items
                               from u in t.Supplier.DefaultIfEmpty()
select new {
ItemName = t.Name
ItemSupplierName = u?.SupplierName
}

The ?. syntax is a new feature in C#6 and is a short cut for checking that the variable isn't null before deferencing it. The fact that you're getting that error on the build server shows that the build server is still running an older version of the compiler.

If you can, get the build agent machine upgraded to use the same version of C# and .NET that you're using to develop with.

If you can't get the build agent upgraded to use the latest version of C# (and .NET) then you'll have to go back to the old way of checking for null:

ItemSupplierName = u != null ? u.SupplierName : null

This is the so called " null conditional operator ", which is available in C# 6 and later. It makes sure that the given term evaluates to null if the part before the ? is null .

For example:

String x = objectVariable?.StringProperty;

assigns null to x in case objectVariable or StringProperty are null . If both are not null, x will contain the value of StringProperty .

The nice thing about it is that you can chain it:

String s = object1?.SomeList?[0]?.SubProperty?.Value;

This replaces structures like:

String s = null;
if (object1 != null && 
    object1.SomeList!= null && 
    object1.SomeList[0] != null &&
    object1.SomeList[0].SubProperty != null)
  s = object1.SomeProperty.SubProperty.Value;

Another way to use it is when raising events. Up to C# 6 you wrote something like this:

private event EventHandler<EventArgs> MyEvent;

if (MyEvent != null)
    MyEvent(this, EventArgs.Empty);

Now you can just write

MyEvent?.Invoke(this, EventArgs.Empty);

Your code is C#6 code, it looks like you are trying to compile it with an older version.

You have to replace u? with a ternary operator:

ExpandedItems = from t in items
                from u in t.Supplier.DefaultIfEmpty()
                select new {
                    ItemName = t.Name
                    ItemSupplierName = (u == null ? null : u.SupplierName)
                }

Have a look here , search for "Null-conditional operators".

As @ChrisF has mentioned above - You'll need to upgrade build agent to the latest version.

Operator ?. is the new syntax of C# 6 and allows for user check if the object is null. If result of operator is null, it returns null itself instead of resolving the inner variable/attribute.

So basically previous syntax:

ItemSupplierName = (u != null) ? u.SupplierName : "";

Has moved to simplier version in C# 6:

ItemSupplierName = u?.SupplierName ?? "";

As answered at other question , You can go get upgrade MS Build tools 2015 which supports C# 6 syntax & provides compiler for this. Or You can also change the syntax to the previous version of C# to get it compiled.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM