FirstOrDefault() result of a struct collection?

2019-04-17 20:43发布

So I've got a collection of structs (it's actually a WCF datacontract but I'm presuming this has no bearing here).

List<OptionalExtra> OptionalExtras;

OptionalExtra is a struct.

public partial struct OptionalExtra

Now I'm running the below statement:

OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra != null)
{

}

Now this won't compile:

the operator != cannot be applied to opperands of type OptionalExtra and '<null>'

After a little googling I realised it's because OptionalExtra is a struct. Which I believe is not nullable unless defined as a nullable type?

So my question is, if my where statement returns no results what will be the outcome of the FirstOrDefault call? Will it thrown an exception?

Incidently this should never happen but better safe than sorry.

7条回答
Root(大扎)
2楼-- · 2019-04-17 21:10

If default(OptionExtra) is still a valid value, it's better to change your code to this

var results = OptionalExtras.Where(w => w.Code == optExtra.Code).Take(1).ToList();
if (results.Any()) {
   multiOptExtra = results[0]
}
查看更多
Evening l夕情丶
3楼-- · 2019-04-17 21:13

Assuming Code is a string for the purposes of my answer, you should be able just to test that value for its default.

OptionalExtra multiOptExtra = OptionalExtras.Where(w => w.Code == optExtra.Code).FirstOrDefault();
if (multiOptExtra.Code != null)
{

}
查看更多
【Aperson】
4楼-- · 2019-04-17 21:14

its provide you defualt value for your structure like as below

int[] numbers = { };
int first = numbers.FirstOrDefault();
Console.WriteLine(first);//this print 0 as output 

other option to handle is make use of default value like as below

List<int> months = new List<int> { };
// Setting the default value to 1 by using DefaultIfEmpty() in the query. 
int firstMonth2 = months.DefaultIfEmpty(1).First();
Console.WriteLine("The value of the firstMonth2 variable is {0}", firstMonth2);
查看更多
走好不送
5楼-- · 2019-04-17 21:15

As others have said, the result of your code when no elements match will be:

default( OptionalExtra )

If you want a null returned, you can cast your list to OptionalExtra?

OptionalExtra? multiOptExtra = OptionalExtras.Cast<OptionalExtra?>().Where( ...

You can then test for null

查看更多
干净又极端
6楼-- · 2019-04-17 21:23

If you want to check for null, use System.Nullable collection:

var OptionalExtras = new List<OptionalExtra?>();
/* Add some values */
var extras = OptionalExtras.FirstOrDefault(oe => oe.Value.Code == "code");
if (extras != null)
{
    Console.WriteLine(extras.Value.Code);
}

Note that you have to use Value to access the element.

查看更多
姐就是有狂的资本
7楼-- · 2019-04-17 21:25

The result will be the default value of your struct, e.g. default(OptionalExtras).

Whereas for a reference type the default value is null.

查看更多
登录 后发表回答