RuntimeBinderException 异常

异常描述

最近使用Redis发现了一个十分诡异的异常,异常如下:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: “StackExchange.Redis.IBatch”未包含“HashSetAsync”的定义
   在 CallSite.Target(Closure , CallSite , IBatch , String , String , Object )
   在 System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid4[T0,T1,T2,T3](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   在 DbCommandExecutor.RunCommand(RedisCmd cmdInfo, Boolean isMutiWrite)

原因分析

乍一看,似乎是引用的类库存在问题,不包含HashSetAsync的定义,但通过dotPeek反编译发现“HashSetAsync”方法是确实存在的,并非问题所在,再仔细查看RuntimeBinderException产生的原因有两种:

  • 第一种:'Microsoft.CSharp.RuntimeBinder.Binder' is not defined or imported,该异常是由于Microsoft.CSharp引用缺失导致,直接引用即可;
  • 第二种:是因为匿名类型不能跨程序集,需要在源程序集中引入[assembly: InternalsVisibleTo("XXX.XXX.XXX")]

分析代码发现,因为某些不可描述的原因,我使用了dymaic类型:

    /// <summary>
    /// Redis执行参数。
    /// </summary>
    public class RedisParam
    {
        /// <summary>
        /// Redis 键。
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// Redis 复合结构中的键。
        /// </summary>
        public string StructKey { get; set; }

        /// <summary>
        /// 数据结构中的值。
        /// </summary>
        public dynamic StructVal { get; set; }
    }

不过RedisHash本身就是一个string类型的field和value的映射表,略做调整,并把dynamic改为string,算是解决了,这个问题本身涉及到了本人的知识盲区和设计上的失误导致的,小计一笔,避免再犯。

原文地址:https://www.cnblogs.com/krockey/p/14335245.html