c# – 方法未被动态泛型类型解析
我有这些类型:
public class GenericDao<T> { public T Save(T t) { return t; } } public abstract class DomainObject { // Some properties protected abstract dynamic Dao { get; } public virtual void Save() { var dao = Dao; dao.Save(this); } } public class Attachment : DomainObject { protected dynamic Dao { get { return new GenericDao<Attachment>(); } } } 然后当我运行这个代码,它失败与RuntimeBinderException:最佳重载方法匹配’GenericDAO< Attachment> .Save(附件)’有一些无效的参数 var obj = new Attachment() { /* set properties */ }; obj.Save(); 我已经验证了在DomainObject.Save()“这”绝对是Attachment,所以错误并没有真正的意义.任何人都可以清楚,为什么方法不能解决? 一些更多的信息 – 如果将DomainObject.Save()的内容更改为使用反射,则会成功: public virtual void Save() { var dao = Dao; var type = dao.GetType(); var save = ((Type)type).GetMethod("Save"); save.Invoke(dao,new []{this}); } 解决方法
问题是在编译时解决了动态方法调用的某些方面.这是设计.从语言规范(强调我的):
这里,组成的表达式具有编译时类型DomainObject< int> (简化:源代码是一种通用类型,因此我们应该如何“查看”这个编译时类型,但希望我的意思是被理解),因为这不是动态类型或type-parameter,其类型作为其编译时类型. 所以绑定器查找一个方法Save一个类型为DomainObject< int>的单个参数(或者在编译时传递类型为DomainObject< int>的对象是合法的). 看起来有点像这样在编译时发生了约束: // Extra casts added to highlight the error at the correct location. // (This isn't *exactly* what happens.) DomainObject<int> o = (DomainObject<int>) (object)this; GenericDao<Attachment> dao = (GenericDao<Attachment>)Dao; // Compile-time error here. // A cast is attempted from DomainObject<int> -> Attachment. dao.Save(o); 但是,由于GenericDao< Attachment>所关心的唯一候选方法 – 是附件保存(附件),对于此方法,从参数类型(DomainObject< int>)到参数类型(Attachment)不存在隐式转换. 所以我们得到编译时错误: The best overloaded method match for 'GenericDao<Attachment>.Save(Attachment)' has some invalid arguments Argument 1: cannot convert from 'DomainObject<int>' to 'Attachment' 而这是使用动态版本延迟到运行时的错误.反射没有相同的问题,因为它不会在编译时尝试提取与方法调用相关的“局部”信息,而不像动态版本. 幸运的是,修复很简单,推迟了组件表达式的评估: dao.Save((dynamic)this); 这使我们进入选项1(编译时类型动态).构成表达式的类型推迟到运行时,这有助于我们绑定到正确的方法.那么代码的静态等价物就像: // Extra casts added to get this to compile from a generic type Attachment o = (Attachment)(object)this; GenericDao<Attachment> dao = (GenericDao<Attachment>)Dao; // No problem,the Save method on GenericDao<Attachment> // takes a single parameter of type Attachment. dao.Save(o); 这应该工作正常. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |