我有这些类型:
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
我已经验证在 DomainObject.Save() 中“this”肯定是附件,所以这个错误没有意义。任何人都可以阐明为什么该方法无法解析吗? 更多信息 - 如果我将 DomainObject.Save() 的内容更改为使用反射,它会成功:var obj = new Attachment() { /* set properties */ };
obj.Save();
public virtual void Save() {
var dao = Dao;
var type = dao.GetType();
var save = ((Type)type).GetMethod("Save");
save.Invoke(dao, new []{this});
}
最佳答案
问题是动态方法调用的某些方面是在编译时解决的。这是设计使然。来自语言规范(强调我的):
7.2.3 Types of constituent expressions
When an operation is statically bound, the type of a constituent expression (e.g. a receiver, and argument, an index or an operand) is always considered to be the compile-time type of that expression. When an operation is dynamically bound, the type of a constituent expression is determined in different ways depending on the compile-time type of the constituent expression:
• A constituent expression of compile-time type dynamic is considered to have the type of the actual value that the expression evaluates to at runtime
• A constituent expression whose compile-time type is a type parameter is considered to have the type which the type parameter is bound to at runtime
• Otherwise the constituent expression is considered to have its compile-time type.
在这里,组成表达式 this有一个编译时类型 DomainObject<int> (简化:源代码是通用类型,因此我们应该如何“查看” this 的编译时类型变得复杂,但希望我的意思能够理解),并且由于这不是动态类型或类型参数,其类型被视为其编译时类型。
所以 Binder 寻找一个方法Save采用 DomainObject<int> 类型的单个参数(或者在编译时向其传递 DomainObject<int> 类型的对象是合法的)。
如果绑定(bind)发生在编译时,它看起来有点是这样的:
// 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>是Attachment Save(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'
this 是延迟到运行时使用 dynamic 的错误版本。与 dynamic 不同,反射没有相同的问题,因为它不会尝试在编译时提取有关方法调用的“部分”信息。版本。
幸运的是,修复很简单,推迟对构成表达式类型的评估:
dao.Save((dynamic)this);
这使我们进入选项 1(编译时类型 dynamic)。 constituent-expression 的类型被推迟到运行时,这有助于我们绑定(bind)到正确的方法。然后代码的静态绑定(bind)等价物是这样的:
// 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);
应该可以正常工作。
关于c# - 未为动态泛型解析方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4674564/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案