私有内部 class 上的动态失败
Dynamic fails on private inner class
当我 运行 以下代码时,我得到 RuntimeBinderException: 'object' does not contain a definition for 'SetIt'
.
public interface IInput { }
public interface IThing<in TInput>
{
void SetIt(TInput value);
}
public class ThingMaker
{
private class Thing<TInput> : IThing<TInput>
where TInput : IInput
{
public void SetIt(TInput value){}
}
private class Input : IInput {}
public IThing<IInput> GetThing()
{
return new Thing<IInput>();
}
public IInput GetInput()
{
return new Input();
}
}
class Program
{
static void Main(string[] args)
{
var thingMaker = new ThingMaker();
var input = thingMaker.GetInput();
dynamic thing= thingMaker.GetThing();
thing.SetIt(input);
}
}
如果我将 thing
切换为 var
,它可以正常工作。很明显,thing
有 SetIt
。当我使用动态时为什么会失败?任何作为 var
工作的东西在 dynamic
时都不应该工作吗?
我认为这与 Thing<TInput>
是私有内部 class 有关,因为它在我制作它时起作用 public.
这是您的问题的一个简单示例:
class A
{
class B
{
public void M() { }
}
public static object GetB() { return new B(); }
}
class Program
{
static void Main(string[] args)
{
dynamic o = A.GetB();
o.M();
}
}
泛型和接口只是一种干扰。
问题是类型 B
(或者在您的情况下,Thing<IInput>
)是私有类型 class,因此在调用站点无法解析为该实际类型.回想一下,dynamic
只是一个 object
变量,但编译已推迟到 运行 时间。它的目的不是让你在 运行 时间做你本来无法做的事情,并且 "wouldn't otherwise be able to do" 是根据调用站点的可访问类型来判断的(在这种情况下, 是 object
).
就 运行time 活页夹而言,类型只是 object
(因此错误消息告诉您 object
不包含您想要的成员) .
当然,理论上 dynamic
可以有不同的实现方式,并且可以对有效类型进行更深入的搜索,它可以将对象视为将成员绑定到对象(即实现的接口而不仅仅是对象的实际类型)。但这并不是它的实现方式,而且这样做的成本要高得多(无论是在原始设计和实现方面,当然还是在 运行 的代码时间成本方面,使用 dynamic
).
相关阅读(可以重复):
Is this a bug in dynamic?
Is this a hole in dynamic binding in C# 4?
当我 运行 以下代码时,我得到 RuntimeBinderException: 'object' does not contain a definition for 'SetIt'
.
public interface IInput { }
public interface IThing<in TInput>
{
void SetIt(TInput value);
}
public class ThingMaker
{
private class Thing<TInput> : IThing<TInput>
where TInput : IInput
{
public void SetIt(TInput value){}
}
private class Input : IInput {}
public IThing<IInput> GetThing()
{
return new Thing<IInput>();
}
public IInput GetInput()
{
return new Input();
}
}
class Program
{
static void Main(string[] args)
{
var thingMaker = new ThingMaker();
var input = thingMaker.GetInput();
dynamic thing= thingMaker.GetThing();
thing.SetIt(input);
}
}
如果我将 thing
切换为 var
,它可以正常工作。很明显,thing
有 SetIt
。当我使用动态时为什么会失败?任何作为 var
工作的东西在 dynamic
时都不应该工作吗?
我认为这与 Thing<TInput>
是私有内部 class 有关,因为它在我制作它时起作用 public.
这是您的问题的一个简单示例:
class A
{
class B
{
public void M() { }
}
public static object GetB() { return new B(); }
}
class Program
{
static void Main(string[] args)
{
dynamic o = A.GetB();
o.M();
}
}
泛型和接口只是一种干扰。
问题是类型 B
(或者在您的情况下,Thing<IInput>
)是私有类型 class,因此在调用站点无法解析为该实际类型.回想一下,dynamic
只是一个 object
变量,但编译已推迟到 运行 时间。它的目的不是让你在 运行 时间做你本来无法做的事情,并且 "wouldn't otherwise be able to do" 是根据调用站点的可访问类型来判断的(在这种情况下, 是 object
).
就 运行time 活页夹而言,类型只是 object
(因此错误消息告诉您 object
不包含您想要的成员) .
当然,理论上 dynamic
可以有不同的实现方式,并且可以对有效类型进行更深入的搜索,它可以将对象视为将成员绑定到对象(即实现的接口而不仅仅是对象的实际类型)。但这并不是它的实现方式,而且这样做的成本要高得多(无论是在原始设计和实现方面,当然还是在 运行 的代码时间成本方面,使用 dynamic
).
相关阅读(可以重复):
Is this a bug in dynamic?
Is this a hole in dynamic binding in C# 4?