I have an object whose base type is exposed to be at compile time, but whose runtime type is internal and for all practical purposes I am unable to get to the type at compile time.
However, I want to be able to access a property on its instance at runtime.
I understand that without knowing the type at compile time, I cannot create a typed delegate.
What is the most performant way of accessing this property? DynamicInvoke?
Imagine this is a file: Hidden.cs
internal class Hidden
{
public string SomeProp { get { .. } }
}
I can't type the following in my code Func someExpression = Expression.Lambda < Func < Program, string > > ...
I just want to confirm that my only option is DynamicInvoke when I can't reference the type at compile time.
You can create Func<object, string>
, then cast the object
to Hidden
(your type) and then access SomeProp
. All of this can be done in Expressions like this:
internal class Program
{
private static Func<object, string> somePropFunc;
private static void Main(string[] args)
{
//Create instance somehow
Type type = typeof(Hidden);
object hiddenInstance = Activator.CreateInstance(type);
//Cache the delegate in static field, and use it any number of times
somePropFunc = GetSomePropAccessorMethod();
for (int i = 0; i < 100; i++)
{
// Access Hidden.SomeProp
Console.WriteLine(somePropFunc(hiddenInstance));
}
}
private static Func<object, string> GetSomePropAccessorMethod()
{
Type type = typeof(Hidden);
PropertyInfo prop = type.GetProperty("SomeProp");
var parameter = Expression.Parameter(typeof(object), "hidden");
var castHidden = Expression.TypeAs(parameter, type);
var propertyAccessor = Expression.Property(castHidden, prop);
return Expression.Lambda<Func<object, string>>(propertyAccessor, parameter).Compile();
}
}
internal class Hidden
{
public string SomeProp
{
get
{
return "Some text";
}
}
}
Which prints "Some text" in console 100 times.