user1339253
user1339253

Reputation: 149

Property reflection inside of a LINQ query doesn't behave as expected

Given the following lines of code in C#:

var testvalue = result[0]
  .GetType()
  .GetProperty(propertyNameToFilterOn)
  .GetValue(result[0], null);

var test = result
  .Where(x => x
      .GetType()
      .GetProperty(propertyNameToFilterOn)
     ?.GetValue(x, null) == "46ee6799-2bed-4a7a-93f8-0839affbd218")
  .ToList();

result obviously contains a collection of objects. The first line gives me a value (46ee6799-2bed-4a7a-93f8-0839affbd218). However, the second line returns 0 objects in the list. The first line confirms that the first object in the collection does have the value I'm filtering on in the second line, while the second line tells me that no objects in the collection has that value on the property I'm checking. Can someone explain why this does not work? And potentially provide an alternative?

Upvotes: 0

Views: 208

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Since ?.GetValue(x, null) returns instance of object, when you compare it with "46ee6799-2bed-4a7a-93f8-0839affbd218" you compare references, not values:

string st = "46ee6799-2bed-4a7a-93f8-0839affbd218";

// Some manipulations (we don't want the compiler to intern strings)
object o = (st + " ").Trim();

Console.WriteLine(o == st ? "Equal" : "Not Equal");
Console.WriteLine(string.Equals(o, st) ? "Equal" : "Not Equal");

Outcome:

Not Equal
Equal

Use string.Equals instead of == in order to compare values:

var test = result
  .Where(x => string.Equals(x
      .GetType()
      .GetProperty(propertyNameToFilterOn)
     ?.GetValue(x, null), "46ee6799-2bed-4a7a-93f8-0839affbd218"))
  .ToList();

Upvotes: 1

Related Questions