Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does List<T>.Find work when T is a struct?

I have a List<KeyValuePair<string, othertype>>. I need to do something along the lines of

list.Find(x=>x.Key=="foobar")

However, if that doesn't exist in the list, what will the behavior be? Usually it would return null, but structs can't be null.

like image 215
Earlz Avatar asked Oct 01 '12 15:10

Earlz


People also ask

Can a struct contain a list?

Yes you can have a list in struct but you cannot initialise it with a field initialiser and instead you must use the constructor.

Can you inherit from a struct?

Structs cannot have inheritance, so have only one type. If you point two variables at the same struct, they have their own independent copy of the data. With objects, they both point at the same variable.

Can a struct hold a reference?

Yes they can. It depends. Many hold the stance that a struct should be immutable, and in this case, holding a reference to an object could mean it isn't.

Is struct passed by value or reference?

Because a struct is a value type, when you pass a struct by value to a method, the method receives and operates on a copy of the struct argument. The method has no access to the original struct in the calling method and therefore can't change it in any way. The method can change only the copy.


2 Answers

My advice is to use FindIndex for non nullable types

int index = list.FindIndex(x => x.Key == "foobar");
if (index >= 0) {
    // found!
    UseResult(list[index]);
}

The default value default(T) is returned if Find() is not successful. For non nullable types, this result cannot be distinguished from regular entries having the default value. This is also true for nullable types when the list might contain regular null entries.

like image 104
Olivier Jacot-Descombes Avatar answered Sep 18 '22 05:09

Olivier Jacot-Descombes


It will return the default(T) which will be the same as new KeyValuePair<string, othertype>>(), that is, a default initialized struct.

Basically, the default for reference types is always null, and for value types (including struct) it's the default (0 for numerics, false for bool, a struct with every field defaulted for structures, etc.)

So, for a default(KeyValuePair<string, othertype>>) you'd get back a KVP where the Key was null (default for string) and whatever the default(othertype) would be (as in the examples above)...

From the MSDN:

The first element that matches the conditions defined by the specified predicate, if found; otherwise, the default value for type T.

Using this, if you wanted to check and see if you got back the default, I'd recommend checking for yourResult.Key != null to see if you got a result, or you could use a different Find method such as FindIndex as Olivier suggests.

like image 22
James Michael Hare Avatar answered Sep 22 '22 05:09

James Michael Hare