gpt4 book ai didi

c# - 调用对象实际类型的公共(public)方法

转载 作者:太空宇宙 更新时间:2023-11-03 12:12:16 24 4
gpt4 key购买 nike

考虑以下代码

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);

通过反射,我可以获得 Users 的值,而它是一个 private 类的列表。现在我想对用户调用 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是私有(private)的。
2. 在 object { List<InaccessibleClass> } 上调用公共(public) List 方法的正确方法是什么? ?

最佳答案

  1. Why I can't call Clear() when cast usersOfSample into dynamic?

因为

1.1 During runtime, is usersOfSampleDyn resolved as a List<T> or a object { List<T> }?

object {List<T>} .

编辑:

The reason dynamic treats the object as object is that dynamic will be treated as the most derived type that is accessible to where it is called.

Jon Hanna's comment 中所述.

1.2 If usersOfSampleDyn was resolved as a object { List<T> }, how to convert it into List or anything I can call Clear() on?

List<T>实现非泛型 IList ,简单地转换为它:

((IList)usersOfSample).Clear();
  1. What's the correct way to call a public List method on object { List<InaccessibleClass> }?

你不知道。如果类(class)无法访问,那么这样做是有原因的。如果是您自己的代码,请更改对象可见性,否则不要在外部代码的内部状态中乱搞,它可能会在任何时候中断并产生意想不到且难以调试的副作用。

但如果您真的需要它,可以反射或转换为 IList。

关于c# - 调用对象实际类型的公共(public)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51532079/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com