What is System.Reflection.RuntimePropertyInfo and how do I compare it? - c#

I was suprised to see that the actual type of the object I get with x.GetType().GetProperty("Foo") is not System.Reflection.PropertyInfo but System.Reflection.RuntimePropertyInfo.
I don't see this type documentation in msdn or elsewhere.
My actual problem grows from reference-comparing two properties. I receive a property from third-party lib and compare it with a property which I get with .GetProperty("Foo") on the same type. I expected properties to be the same object (and they looks like the same property in "Locals" window while debugging), but they are not (GetHashCode result is different). So, I think it can somehow be related with the actual type of the property object which is System.Reflection.RuntimePropertyInfo.
What is System.Reflection.RuntimePropertyInfo? How to compare it? Does it behaves the same as usual PropertyInfo?

RuntimePropertyInfo is an internal implementation. It is a PropertyInfo, and in fact, GetProperty returns PropertyInfo (even if the underlying type is RuntimePropertyInfo).
The third-party lib is probably getting the property of a different type than you are?
new blah().GetType().GetProperty("Test") == new blah().GetType().GetProperty("Test")
Returns true.

PropertyInfo is an abstract class while RuntimePropertyInfo is the concrete implementation of PropertyInfo.
When we call Type.GetProperties() or Type.GetProperty() they actually returns the RuntimePropertyInfo.
The reason you are getting reference not equal could be because of the Type signature difference in the third-party lib.

Related

How to get the list of Enum properties of a class?

Closely related to How to get the list of properties of a class?, I've gotten as far as that question goes but I'm interested in knowing which of the returned properties are enumerations. My first (unlikely) guess was along the lines of:
foo A;
foreach (var property in A.GetType().GetProperties())
{
if (property.PropertyType is Enum)
//Celebrate
}
This did not work. It's valid, but Visual Studio was even able to warn in advance that "The given expression is never of the provided ('System.Enum') type".
To my understanding, C# Enums are wrappers over top of primitive counting types (defaulting with int, but also possibly byte, short, etc). I can easily test to see of the properties are of these types, but that will lead me to a lot of false positives in my search for Enums.
You are almost there. Just use
if (property.PropertyType.IsEnum)
// Celebrate
In .NET 4.5, you might need to get a TypeInfo object from the property type.
property is a PropertyInfo object.
PropertyInfo doesn't inherit Enum, so that can never be true.
You want to check the PropertyType – the Type object describing the property's return type.
if (property.PropertyType is Enum) won't work either, for the same reason – Type doesn't inherit Enum.
Instead, you need to look at the properties of the Type object to see whether it's an enum type.
In this case, you can just use its IsEnum property; in the more general case, you would want to call IsSubclassOf().

C#: return stong types from reflection

In the latest version of C#, is it possible to convert a dynamic type to a strong type, if you know the type in advance?
I'm using reflection to call a method on an object, which returns to a var:
var returnVal = context.GetType().InvokeMember(MethodName, BindingFlags.InvokeMethod, null, context, lParams.ToArray());
I can easily get the type being returned to returnVal. Is it possible to cast\convert thins to a more strongly typed version?
EDIT FOR CLARITY:
In this situation, I know the type being returned but only by string. To get the type, I have to do:
diAssemblies[k].GetType(diAssemblies[k].GetName().Name + "." + returnType)
Where returnType is the name of type being returned.
Ideally, I'd like to be able to get the result of the method invocation in to a strongly typed field.
CONTEXT
I'm loading assemblies containing .edmx files from a directory, then invoking methos on those contexts. At run time, the loader won't know what assemblies it's going to be loading. However, the person using the loader will be aware of the assemblies, methods and types.
This is to create a generic wrapper around database calls through entity framework (with stored procedures), that will be reused elsewhere.
If you don't know the Type statically, how could you use a statically typed reference? What you can do is have the returned type implement an interface you do know about statically, then cast to that interface.
So, if MyStrongType implements IMyStrongBehavior, you can cast the return value to IMyStrongBehavior and use that statically. The underlying value is already strongly typed, regardless of whether you cast it.
Alternately, you can store the return value in a dynamic variable (which will allow you to invoke known methods without an actual statically-typed interface.) The disadvantage here is that you don't get any Intellisense and any mistakes you make won't show up until runtime.
No, you can't get the advantages of a concrete type such as compile time checking and intellisense. This is because you are only actually working out what the type is at run time. It is late bound, which means that it's a job for dynamic and the DLR. You can cast it to an object that you know the actual object will inherit from (e.g. object), but you can't cast to the actual type. You might want to look into generics as an alternative if you had for example:
public T GetReturnVal<T>()
{
return (T)context.GetType().InvokeMember(MethodName, BindingFlags.InvokeMethod, null, context, lParams.ToArray());
}
You would at least be returning a concrete type to callers of type T. But this type has to be set at compile time, i.e. known in advance.
I recomend you read An Introduction to C# Generics as it does exactly what, from the context you've added, you need to do.

Is there a way to use ParameterInfo and PropertyInfo Interchangeably?

To me they are very similar structures. I was hoping there was a way to cast or convert one to the other easily.
I'm using reflection to do some magic. I've chosen the path to use parametrized constructors to create some user selected objects which they fill in values for the parameters using a UI.
The problem is one of the objects takes in a structure as a param and I can't get at the structures properties as parameter infos just property infos.
But I don't want to just reproduce the parameter info code I have now for property infos. It be nice if I could pass in a property info as a parameter info. Everything is really similar except for some names of some properties; ParameterType as opposed to PropertyType and what not.
I may have to do my own conversion or write my own class that houses the properties that I need and just use that custom object instead. Cheers.
No, there is not.
Those two classes represent two very different concepts.
A property is an attribute on an Type. The PropertyInfo class will allow you to set or get the value and will tell you additional information about the Property.
A parameter is an attribute of a method signature (an accessor on a type can have a parameter as well). The ParameterInfo class represents this concept and can tell you the Type of the parameter, the position in the method signature, whether it is an out or ref parameter, etc. See: MSDN doc. A ParameterInfo is not directly associated to a Type.

Getting information about a member invoked using Type.InvokeMember()

I'm using Type.InvokeMember() to dynamically invoke various members of a Type. Since the members can be generic and also include out parameters etc., I'm happy to have the runtime handle this. However, I also need to have additional information about the actual member that's been invoked -- particularly, the return type. If this type is nullable, I need to do some additional processing.
So, I'd like to know if it's possible to get the MemberInfo object corresponding to the member that was invoked through Type.InvokeMember().
Alternatively, is there a variant of InvokeMember() that simply does the lookup and returns the appropriate MemberInfo object but doesn't actually invoke it? I can then analyze the MemberInfo object, and later invoke it directly.
I haven't been able to find any .NET APIs that do this, so I suspect I'll need to handcode it. Let me know if I'm missing something.
Alternatively, is there a variant of InvokeMember() that simply does the lookup and returns the appropriate MemberInfo object
You can use the Type.GetMethod method, giving a description of the desired method (name and parameter types). It returns a MethodInfo object which includes the return type.
typeof(yourType).GetMethod(...);

Get property value dynamically

I have an object which has a huge number of properties. I'd like to get the value of each of those properties by simply looping through the properties collection of the object.
I've looked into the PropertyInfo.GetValue() method however it's not making much sense in the context I have.
Here's an example of what i'm trying to do (this code doesn't work btw):
foreach(var item in dataObjects)
{
foreach(PropertyInfo prop in item.GetType().GetProperties())
{
String value = prop.GetValue().ToString()
}
}
I realise now that getting the value of a property isn't this easy. What am I missing? I don't really understand what I need to pass to the GetValue() method because I simply want the value of the property I'm calling that method on.
Thanks for any help clarifying this for me. I've spent a couple of hours here just banging my head against the desk.
You need to provide the specific object on which you want to call the property in question:
prop.GetValue(item, null);
The PropertyInfo is just metatdata about the property on the type, not on the specific object instance. The PropertyInfo doesn't know which instance it came from (if any) - just the type/class it came from.
You can almost think of the PropertyInfo as just the name of the property. That's not enough information to do anything with it alone - we then have to say "get the value of the property with this name on... what?" On the object we provide.
PropertyInfo represents the property machinery itself (type, get method, set method, et cetera), not a property bound to a specific instance. If the property is nonstatic, you must provide an instance to read that property from -- that's the first parameter to GetValue. In other words, if pi is a PropertyInfo representing the Test property on some class and someObject is an instance of that class:
object a = someObject.Test;
object b = pi.GetValue(someObject, null);
both lines there get the value of the same property on the same object. If the property is static, you don't need to pass the instance, obviously (pass null instead). The second parameter is the index for indexed properties -- C# does not support indexed properties (it supports indexers, which are not exactly the same), so you will likely never need to pass anything but null for that second parameter unless you're working with some type from an assembly written in a language that does support indexed properties (like VB, I believe).

Categories

Resources