此问题与object
和dynamic
之间的一般差异无关,已经得到了解答。以下是针对特定用例的。
假设我有以下界面:
public interface IDoesStuff
{
void Invoke(dynamic foo1, object foo2);
}
假设我有以下类实现IDoesStuff
:
public class DoesStuff1 : IDoesStuff
{
public void Invoke(dynamic foo1, object foo2)
{
...
}
}
这看起来很正常。但是,我可以为参数交换object
和dynamic
。例如,以下类将不生成编译器错误,导致无法实现IDoesStuff
:
public class DoesStuff2 : IDoesStuff
{
public void Invoke(object foo1, dynamic foo2)
{
...
}
}
因此,实现此界面的类似乎允许我不强制参数为object
,而是让我使用dynamic
。并且以一种方式或另一种方式编写将产生编译器错误,具体取决于我们如何使用参数:
public void Invoke(dynamic foo1, object foo2)
{
foo1.Bark(); // compiles
}
public void Invoke(object foo1, dynamic foo2)
{
foo1.Bark(); // does not compile
}
我发现这很奇怪,因为我可能做想要传递object
并只展示它拥有的几种方法。
我还可以尝试查看是否可以使用dynamic
替换另一种类型:
public interface ISomethingElse
{
void DoWork(int foo)
}
public class SomethingElse : ISomethingElse
{
public void DoWork(dynamic foo)
{
...
}
}
不,其他类型会因为没有实现接口而产生编译错误。
那么为什么接口及其实现类之间的dynamic
和object
可互换参数类型呢?
答案 0 :(得分:0)
将参数标记为dynamic
vs object
与C ++中的顶级const
相似。它会影响实现方法中的代码,但不会影响调用者。
请注意dynamic
根本不属于某种类型。它是语法糖,要求编译器将所有用法转换为DLR调用。因此,强制参数类型匹配将完全没有任何效果。
你提议"也许我确实希望传递一个object
并且只暴露它拥有的几种方法"。不可能!
public void DoWork(System.Object foo_param)
{
dynamic foo = foo_param;
foo.MethodNotFoundInSystemObject();
...
}
由于动态处理是在方法内部进行的,并且无法通过更改方法签名的拼写来防止,因此没有理由实际执行它或甚至将其包含在签名中。
也就是说,如果您使用反射来获取与使用MethodInfo
参数类型声明的方法相对应的dynamic
,那么您会发现它确实是typeof(System.Object)
。