简体   繁体   English

在私有类型上动态抛出Microsoft.CSharp.RuntimeBinder.RuntimeBinderException

[英]Dynamic throwing Microsoft.CSharp.RuntimeBinder.RuntimeBinderException on private types

I need to write some code to clone a HashSet of any type but the type is not known beforehand. 我需要编写一些代码来克隆任何类型的HashSet,但是该类型事先未知。 Due to the lack of a non generic interface (unlike dictionary there is no ISet interface just a ISet<>) I have to use reflection. 由于缺少非通用接口(与字典不同,没有ISet接口,只有ISet <>),我不得不使用反射。 I decided to let dynamic handle the reflection work for me but now iam running into a seemingly very weird problem when I run the following code (heavily simplified from the real world code): 我决定让动态处理对我来说有效,但是现在当我运行以下代码(与真实世界的代码相比已大大简化)时,我遇到了一个看似非常奇怪的问题:

class Program
{
    static void Main(string[] args)
    {
        HashSet<ReferenceType> source = new HashSet<ReferenceType>();
        ExtMethodsCloning.DeepClone(source);
    }

    private class ReferenceType { }
}

public static class ExtMethodsCloning
{
    public static void SomeCloningMethodThatHappensToCallClear(dynamic baseObj)
    {
        baseObj.Clear();
    }
}

If you move DeepClone to the program class or make ReferenceType public it works. 如果将DeepClone移至程序类或将ReferenceType公开,则它可以工作。 It somehow needs to see ReferenceType in order to work. 它必须以某种方式查看ReferenceType才能起作用。 Even though we are only interested in calling the Clear method which isnt even defined on ReferenceType but on HashSet<>. 即使我们只对调用Clear方法感兴趣,该方法甚至不是在ReferenceType上而是在HashSet <>上定义的。

How can I workaround this while not having to resort to manually doing the reflection work? 如何解决此问题,而不必求助于手动进行反射工作? Remember the type is not know at compile time so no generics. 记住类型在编译时是未知的,所以没有泛型。

EDIT: iam aware of the fact that at some point I would have to create new instances and thus have to call private constructors. 编辑:我知道一个事实,在某个时候我将不得不创建新的实例,因此必须调用私有构造函数。 If its even possible to call a constructor using dynamic I would expect an error in that case (and workaround it by using reflection) but not now when just calling Clear on the HashSet. 如果甚至可以使用动态调用构造函数,那么在这种情况下(并且通过使用反射来解决),我会期望出现错误,但是现在仅在HashSet上调用Clear时不会出现此错误。

I don't understand the need for dynamic here. 我不明白这里需要动态。 I'm pretty sure you can do what you need with generics. 我很确定您可以使用泛型来完成所需的工作。

EDIT: How to call a generic method by reflection: 编辑:如何通过反射调用通用方法:

 static void Main(string[] args)
 {
     var hs1 = new HashSet<SomePrivateClass>();
     CallClear(hs1);
 }

 public static void CallClear(object objectThatIsAHashSet)
 {
     var method = typeof(Program).GetMethod("Clear", BindingFlags.Public | BindingFlags.Static);
     var hsGenericType = objectThatIsAHashSet.GetType().GetGenericArguments()[0];
     var genericMethod = method.MakeGenericMethod(hsGenericType);
     genericMethod.Invoke(null, new[] {objectThatIsAHashSet});
 }

private class SomePrivateClass { }

public static void Clear<T>(HashSet<T> hs)
{
    hs.Clear();
}

EDIT 2: Why doesn't it work with dynamic. 编辑2:为什么它不能与动态。

Basically, dynamic only allows access to public members of a type. 基本上,动态仅允许访问类型的公共成员。 As such, it cannot be used to call either a private member, or a private type. 因此,它不能用于调用私有成员或私有类型。 The basic rule is that if you could not refer to a method in a piece of code using it's type, you cannot access it using dynamic (ie you can't use dynamic to break encapsulation). 基本规则是,如果您无法使用代码的类型在代码段中引用该方法,则无法使用动态方法来访问该方法(即,不能使用动态方法来破坏封装)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException错误 - Microsoft.CSharp.RuntimeBinder.RuntimeBinderException Error 发生``Microsoft.CSharp.RuntimeBinder.RuntimeBinderException&#39;&#39; - 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred 访问动态属性会引发“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的异常 - Accessing a dynamic's property threw an exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' 为什么Microsoft.CSharp.RuntimeBinder.RuntimeBinderException如果有调用的方法? - Why a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException if the invoked method is there? 发生了“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的第一次机会异常 - A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred ASP.Net CORE 3.1 - 抛出错误异常:Microsoft.CSharp.dll 中的“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException” - ASP .Net CORE 3.1 - Error Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll LINQ加入Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:&#39;对象&#39;不包含以下内容的定义: - LINQ Join Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 当我尝试在View中访问Model时出现Microsoft.CSharp.RuntimeBinder.RuntimeBinderException - Microsoft.CSharp.RuntimeBinder.RuntimeBinderException when I try to access Model in View Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:“System.__ComObject”不包含“语言”的定义 - Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''System.__ComObject' does not contain a definition for 'Language'' #SpecFlow# For CreateDynamicInstance() - 错误 - Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:最佳重载方法 - #SpecFlow# For CreateDynamicInstance() - error - Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : The best overloaded method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM