我有一个对象,其基类型在编译时公开,但其运行时类型是内部的,并且出于所有实际目的,我无法在编译时获取该类型。
但是,我希望能够在运行时访问其实例上的属性。
据我所知,在编译时不知道类型,我无法创建一个类型化的委托。
访问此属性的最佳方式是什么? DynamicInvoke?
想象一下这是一个文件:Hidden.cs
internal class Hidden
{
public string SomeProp { get { .. } }
}
我无法在我的代码中键入以下内容Func someExpression = Expression.Lambda< Func<程序,字符串> > ...
我只想在编译时无法引用该类型时确认我唯一的选项是DynamicInvoke。
答案 0 :(得分:1)
您可以创建Func<object, string>
,然后将object
转换为Hidden
(您的类型),然后访问SomeProp
。所有这些都可以在这样的表达式中完成:
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";
}
}
}
哪些打印&#34;一些文字&#34;在控制台100次。
答案 1 :(得分:0)
您始终可以使用dynamic
代理,例如Func<dynamic,T>
,T代表您的返回类型。但请记住,动态调度“缓慢”,因为它使用了scènes背后的反射。 DynamicInvoke完全相同,所以它也一样慢。
现在请记住,“慢”非常相对。与静态调用相比,它很慢,几乎是即时的,但这种微优化在实际程序中几乎不可见。
此外,为什么你需要首先调用一个未知类型的对象的属性?对我来说,这听起来就像是在某个地方做出糟糕的设计决定的症状。例如,考虑让相关类型从公共基类继承/实现相同的接口,突然你的问题消失了。而且你可以获得更好的表现作为奖励。
修改强>
我一开始并没有意识到您想要访问一个您无法看到的成员。那么反思是你唯一的希望。而且您还需要完全信任地运行您的代码。请记住,班级的原创者决定不让你访问这个成员,他可以有很好的理由。你不应该这样做,除非你真的不能这样做。