markp3rry
markp3rry

Reputation: 734

LINQ query on PropertyInfo list

I have a sub class which is 'derived' (is that the right word) from a base class two levels up. I have a list of all the properties in this class (so that includes properties from the parent, and the parent of the parent). What I want is just the properties where the DeclaringType is "CrazyNinjaBadger" (i.e. only the properties from my sub - class).

I've tried this statement:

PropertyInfo[] properties = type.GetProperties().Select(x => x.DeclaringType.ToString() == "CrazyNinjaBadger");

But I just get

"Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Reflection.PropertyInfo[]'.

Please can someone suggest a statement that will work?

Upvotes: 0

Views: 3886

Answers (6)

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64933

PropertyInfo[] properties = type.GetProperties().Select(x => x.DeclaringType.ToString() == "CrazyNinjaBadger");

Select(...) returns an implemenetation of IEnumerable<T>. The compiler error is very explicit.

Another point is you want to filter properties. .Select(...) is for projecting an enumerable into another of the same or other type.

For example:

IEnumerable<string> strings = new string[] { "0", "1" };

// Converting the string enumerable to an enumerable of integers:
IEnumerable<int> integers = strings.Select(some => int.Parse(some)); 

// Also, convert each strings into an anonymous object!
IEnumerable<object> whoKnows = strings.Select(some => new { Value = some }); 

In order to filter an enumerable you need to use .Where(...).

In the other hand, x.DeclaringType.ToString() == "CrazyNinjaBadger" is correct but it should be x.DeclaringType.Name == "CrazyNinjaBadger" (you don't need to convert the type to string as Type has a property Name).

Finally I'd argue that you don't need to set the result in an array, you can just do this:

IEnumerable<PropertyInfo> properties = 
       type.GetProperties()
          .Where(x => x.DeclaringType.Name == "CrazyNinjaBadger");

Upvotes: 1

thesheps
thesheps

Reputation: 655

You were almost there! Select returns an IEnumerable, but you're trying to set the value of a PropertyInfo array. All you need is an additional call to ToArray and you're there!

PropertyInfo[] properties = type.GetProperties().Select(x => x.DeclaringType.ToString() == "CrazyNinjaBadger").ToArray()

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236208

Use Where to filter properties, and convert result to array:

PropertyInfo[] properties = type.GetProperties()
             .Where(x => x.DeclaringType.ToString() == "CrazyNinjaBadger")
             .ToArray();

Also I believe you want to use type name like this x.DeclaringType.Name == "CrazyNinjaBadger". Btw Select operator projects properties to sequence of boolean values in your case. So, your query actually returns IEnumerable<bool> with results of type string comparison to CrazyNinjaBadger.

Upvotes: 3

Claudio Redi
Claudio Redi

Reputation: 68400

Add ToArray() at the end of the line

PropertyInfo[] properties = type.GetProperties()
    .Select(x => x.DeclaringType.ToString() == "CrazyNinjaBadger")
    .ToArray();

Upvotes: 1

Corey Adler
Corey Adler

Reputation: 16137

You're getting that error because Select() always returns an IEnumerable.

Just Add .ToArray() at the end of the line to make it work.

Upvotes: 1

Gopesh Sharma
Gopesh Sharma

Reputation: 7030

PropertyInfo[] properties = type.GetProperties()
                   .Select(x => x.DeclaringType.ToString() == "CrazyNinjaBadger")
                   .ToArray();

The ToArray() needs to be added to convert to Array...

Upvotes: 1

Related Questions