这是动态的错误吗? [英] Is this a bug in dynamic?
问题描述
在泛型类上使用 dynamic
实现动态调度时,并且泛型类型参数是另一个类的私有内部类,运行时绑定程序将引发异常。 p>
例如:
使用系统;
公共抽象类Dispatcher< T> {
public T Call(object foo){return CallDispatch((dynamic)foo); }
受保护的抽象T CallDispatch(int foo);
受保护的抽象T CallDispatch(string foo);
}
公共类程序{
public static void Main(){
TypeFinder d = new TypeFinder();
Console.WriteLine(d.Call(0));
Console.WriteLine(d.Call()));
}
私有类TypeFinder:Dispatcher< CallType> {
受保护的覆盖CallType CallDispatch(int foo){
return CallType.Int;
}
受保护的覆盖CallType CallDispatch(string foo){
return CallType.String;
}
}
私有枚举CallType {Int,String}
}
在这里,将与消息一起引发 RuntimeBinderException
'Dispatcher.CallDispatch(int)'由于其保护级别而无法访问
原因在于类型参数 T
是私有的 CallType
,其中 Dispatcher< T>
无法访问。因此, CallDispatch
必须不可访问-但这不是,因为它可以作为 T
访问。
这是动态
的错误,还是不应该支持?
这是一个错误。如果您可以(并且可以)静态进行呼叫,则应该可以动态进行呼叫。
具体来说,以下代码有效:
使用系统;
公共抽象类Dispatcher< T> {
public T Call(object foo)
{
return CallDispatch((((object)(dynamic)foo).ToString());
}
受保护的抽象T CallDispatch(int foo);
受保护的抽象T CallDispatch(string foo);
}
公共类程序{
public static void Main(){
TypeFinder d = new TypeFinder();
Console.WriteLine(d.Call(0));
Console.WriteLine(d.Call()));
}
私有类TypeFinder:Dispatcher< CallType> {
受保护的覆盖CallType CallDispatch(int foo){
return CallType.Int;
}
受保护的覆盖CallType CallDispatch(string foo){
return CallType.String;
}
}
私有枚举CallType {Int,String}
}
请注意,我已经使用 ToString()
来知道静态类型,C#编译器和CLR允许此上下文访问私有类型 CallType
,因此DLR也应允许。
When implementing dynamic dispatch using dynamic
on a generic class, and the generic type parameter is a private inner class on another class, the runtime binder throws an exception.
For example:
using System;
public abstract class Dispatcher<T> {
public T Call(object foo) { return CallDispatch((dynamic)foo); }
protected abstract T CallDispatch(int foo);
protected abstract T CallDispatch(string foo);
}
public class Program {
public static void Main() {
TypeFinder d = new TypeFinder();
Console.WriteLine(d.Call(0));
Console.WriteLine(d.Call(""));
}
private class TypeFinder : Dispatcher<CallType> {
protected override CallType CallDispatch(int foo) {
return CallType.Int;
}
protected override CallType CallDispatch(string foo) {
return CallType.String;
}
}
private enum CallType { Int, String }
}
Here, a RuntimeBinderException
will be thrown with the message
'Dispatcher.CallDispatch(int)' is inaccessible due to its protection level
The reason for the inaccessibility is that the type parameter T
is the private CallType
which Dispatcher<T>
cannot access. Therefore, CallDispatch
must be inaccessible - but it isn't, because it's accessible as T
.
Is this a bug with dynamic
, or is this not supposed to be supported?
It's a bug. If you can make the call statically (and you can), you should be able to make it dynamically.
Specifically, the following code works:
using System;
public abstract class Dispatcher<T> {
public T Call(object foo)
{
return CallDispatch(((object)(dynamic)foo).ToString());
}
protected abstract T CallDispatch(int foo);
protected abstract T CallDispatch(string foo);
}
public class Program {
public static void Main() {
TypeFinder d = new TypeFinder();
Console.WriteLine(d.Call(0));
Console.WriteLine(d.Call(""));
}
private class TypeFinder : Dispatcher<CallType> {
protected override CallType CallDispatch(int foo) {
return CallType.Int;
}
protected override CallType CallDispatch(string foo) {
return CallType.String;
}
}
private enum CallType { Int, String }
}
Note that I've used ToString()
to make the static type known, the C# compiler and CLR allow this context to access the private type CallType
, so the DLR should allow it as well.
这篇关于这是动态的错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!