【发布时间】:2019-01-03 01:13:31
【问题描述】:
考虑下面的代码
using System.Reflection;
public class Sample {
private class User {
public string Name;
}
private List<User> Users = new List<User> {
new User() { Name = "Alice" },
new User() { Name = "Bob" }
};
}
var sample = new Sample();
var usersOfSample = typeof(Sample).GetField("Users", BindingFlags.Instance |
BindingFlags.NonPublic).GetValue(sample);
通过反射,我可以获得用户的价值,而它是一个 private 类的 List。现在我想对用户调用 List.Clear()。
我的第一个想法是将其转换为动态的。但是,下面的代码并没有达到我的预期。
dynamic usersOfSampleDyn = (usersOfSample as dynamic);
usersOfSampleDyn.Clear();
它抛出一个 RuntimeBinderException。
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'Clear'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at MyCode
后来我在 C# Interactive 中尝试了这段代码,它说
'object' does not contain a definition for 'Clear'
+ System.Dynamic.UpdateDelegates.UpdateAndExecute1<T0, TRet>(System.Runtime.CompilerServices.CallSite, T0)
使用反射调用该方法有效,如下
usersOfSample.GetType().GetMethod("Clear").Invoke(usersOfSample, new object[0]);
这是我的问题:
1. 为什么我在将 usersOfSample 转换为动态时不能调用 Clear()?
1.1 在运行时,usersOfSampleDyn 是解析为List<T> 还是object { List<T> }?
1.2 如果 usersOfSampleDyn 被解析为object { List<T> },如何将其转换为List<T> 或我可以调用Clear() 的任何内容?
注意:T 是私有的。
2. 在object { List<InaccessibleClass> } 上调用公共List 方法的正确方法是什么?
【问题讨论】:
-
我不确定您所说的
dynamic { List<T> }甚至dynamic { object { List<T> } }是什么意思。usersOfSampleDyn当然是dynamic,它在运行时的类型被解析为object。但是,如果您能提供您收到的确切错误消息,那就太好了。 -
如果您知道您正在使用
List<T>,您可以转换为非通用IList并使用它。 -
@thehennyy 我认为 OP 的问题是
T在Sample类中是 private 的。这让我想知道为什么如果 OP 在Sample-class 之外也需要它,它是私有的。 -
@thehennyy 转换为
IList就可以了。 -
@HimBromBeere 是的,这可能是根本问题。
标签: c# dynamic reflection