Water Cooler v2
Water Cooler v2

Reputation: 33880

Should I even check for a default value when calling IEnumerable<T>.FirstOrDefault where T: struct

I have a sequence of structs like so:

struct Foo { }

...

// somewhere else
var foos = GetListOfFoos();

...

// somewhere else
var foo = foos.FirstOrDefault();

Now, should I just go ahead and use the foo I just retrieved without worrying about nullability, of course because structs are not nullable since they're value types.

It just feels a bit worrying.

I know this is a stupid question and the answer is, "Yes, just use it without any checks for null." But I don't know why I am asking this even or what the question here is.

I am not missing anything by not checking for nullability here, right? There cannot be an invalid state for structs put inside that IEnumerable<T>, right?

Of course, I understand that if Foo had uninitialized members because it declared a parameterized ctor that did not initialize each and every member, one or more members of the instance of Foo will be in an unsable state. But as such each instance of Foo in that list will amount to something and there's no need to check for nulls or anything as there is no such thing as default(Foo), right? Of course, just confirming.

Upvotes: 1

Views: 51

Answers (2)

Tim Schmelter
Tim Schmelter

Reputation: 460238

Even if value types are not null you should worry about this value being the default value if that was exceptional or not expected.

there is no such thing as default(Foo)

Sure, It will return an instance of this type where all members are nitialized to their default alues.

If you take f.e. struct Guid then default(Guid) returns an instance which is equal to Guid.Empty or new Guid().

So my advice is, don't compare with default(yourStruct) because that could lead to nasty bugs if the default struct could be a valid instance. Instead you could use Any:

bool containsAny = foos.Any();
if(containsAny)
{
    Foo firstFoo = foos.First();
}

MSDN: default

  • returns null for reference types(class types and interface types)
  • zero for numeric value types
  • for user-defined structs, it returns the struct initialized to the zero bit pattern, which produces 0 or null for each member depending on whether that member is a value or reference type. For nullable value types, default returns a System.Nullable<T>, which is initialized like any struct.

Upvotes: 4

Marc Gravell
Marc Gravell

Reputation: 1063724

If T is a struct, you can't check for null: it will never be null, and a real "zero" (equivalent) in the list/sequence will be indistinguishable from "no there weren't any values in the list/sequence".

No, you don't need to check for null here.

Upvotes: 1

Related Questions