This question already has answers here:
Odd behaviour change with var, dynamic and linq combination
(3个答案)
Will the dynamic keyword in C#4 support extension methods?
(4个答案)
已关闭6年。
我在C#中使用动态变量时遇到了问题。这是在编写NancyFx路由模块时出现的,但我将问题归结为以下示例。虽然我在原始代码中收到了一个不同的异常,但是示例代码仍然抛出了一个我认为是错误的异常。有人看到这里发生了什么吗,还是其他人遇到了类似的问题?
请注意,以下帖子可能相关:
StackOverflowException when accessing member of generic type via dynamic: .NET/C# framework bug?
System.Dynamic bug?
编码:
异常(exception):
(3个答案)
Will the dynamic keyword in C#4 support extension methods?
(4个答案)
已关闭6年。
我在C#中使用动态变量时遇到了问题。这是在编写NancyFx路由模块时出现的,但我将问题归结为以下示例。虽然我在原始代码中收到了一个不同的异常,但是示例代码仍然抛出了一个我认为是错误的异常。有人看到这里发生了什么吗,还是其他人遇到了类似的问题?
请注意,以下帖子可能相关:
StackOverflowException when accessing member of generic type via dynamic: .NET/C# framework bug?
System.Dynamic bug?
编码:
class Program
{
static void Main(string[] args)
{
var dictionary = new Dictionary<string, object>();
dictionary.Add("number", 12);
var result = MethodUsesExplicitDeclaration(dictionary);
var result2 = MethodUsesImplicitDeclaration(dictionary);
}
static dynamic MethodUsesExplicitDeclaration(dynamic reallyDictionary)
{
// this works, ostensibly because the local variable is explicitly declared
IDictionary<string, object> dictionary = CastDictionary(reallyDictionary);
return dictionary.Get<int>("number");
}
static dynamic MethodUsesImplicitDeclaration(dynamic reallyDictionary)
{
// this throws an exception, and the only difference is
// that the variable declaration is implicit
var dictionary = CastDictionary(reallyDictionary);
return dictionary.Get<int>("number");
}
static IDictionary<string, object> CastDictionary(dynamic arg)
{
return arg as IDictionary<string, object>;
}
}
static class Extensions
{
public static T Get<T>(this IDictionary<string, object> dictionary, string key)
{
var value = dictionary[key];
if (value is T)
return (T)value;
throw new InvalidOperationException();
}
}
异常(exception):
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException was unhandled HResult=-2146233088 Message='System.Collections.Generic.Dictionary<string,object>' does not contain a definition for 'Get' Source=Anonymously Hosted DynamicMethods Assembly StackTrace: at CallSite.Target(Closure , CallSite , Object , String ) at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1) at DynamicBug.Program.MethodUsesImplicitDeclaration(Object reallyDictionary) in c:\TFS\UnreleasedCode\POC\DynamicBug\DynamicBug\Program.cs:line 28 at DynamicBug.Program.Main(String[] args) in c:\TFS\UnreleasedCode\POC\DynamicBug\DynamicBug\Program.cs:line 16 InnerException:
最佳答案
问题在于,当您未将对象显式分配给IDictionary<string,object>
声明时,该对象仍将是动态类型(请参见图像中的类型解析)。
正如Eric Lippert在https://stackoverflow.com/a/5313149/1039903中指出的那样,对于动态类型,扩展名方法在调用站点将不可用:
我将您的代码加载到一个测试方法中,以向您显示与显式声明相比,在运行时var dictionary
中实际解决的问题。
明确声明:
隐式声明
如果查看dictionary
的类型解析,则显式声明的类型为System.Collection.Generic.IDictionary
,隐式声明的类型为dynamic{System.Collections.Generic.Dictionary}
10-02 03:07