我有两个业务契约(Contract)类:
public BusinessContract
public Person : BusinessContract
在另一个类中,我有以下代码:
private Action<BusinessContract> _foo;
public void Foo<T>( Action<T> bar ) where T : BusinessContract
{
_foo = bar;
}
上面的甚至不能编译,这让我有点困惑。我将 T 限制为 BusinessContract,那么为什么编译器不知道 bar 可以分配给 _foo?
为了解决这个问题,我们尝试将其更改为以下内容:
public void Foo<T>( Action<T> bar ) where T : BusinessContract
{
_foo = (Action<BusinessContract>)bar;
}
现在编译器很满意,所以我在应用程序的其他地方编写了以下代码:
Foo<Person>( p => p.Name = "Joe" );
应用程序在运行时因 InvalidCastException 而崩溃。
我不明白。我不应该能够将我的更具体的类型转换为不太具体的类型并分配它吗?
更新
Jon 回答了这个问题,因此得到了点头,但为了结束这个循环,下面是我们最终解决问题的方式。
private Action<BusinessContract> _foo;
public void Foo<T>( Action<T> bar ) where T : BusinessContract
{
_foo = contract => bar( (T)contract );
}
我们为什么要这样做?我们有一个用于单元测试的假 DAL。对于其中一种方法,我们需要让测试开发人员能够指定该方法在测试期间被调用时应该做什么(这是一种刷新方法,可以从数据库中更新缓存对象)。 Foo 的目的是设置调用刷新时应该发生的事情。 IOW,在本类(class)的其他地方,我们有以下内容。
public void Refresh( BusinessContract contract )
{
if( _foo != null )
{
_foo( contract );
}
}
然后,测试开发人员可以决定在调用 Refresh 时将名称设置为不同的值。
Foo<Person>( p => p.Name = "New Name" );
最佳答案
你搞错了协变和逆变。让我们考虑 Action<object>和 Action<string> .删除实际的泛型,你正在尝试做这样的事情:
private Action<object> _foo;
public void Foo(Action<string> bar)
{
// This won't compile...
_foo = bar;
}
现在假设我们接着写:
_foo(new Button());
没关系,因为 Action<object>可以传递任何对象...但是我们已经用一个必须接受字符串参数的委托(delegate)对其进行了初始化。哎哟。
这不是类型安全的,因此无法编译。
不过,另一种方式会起作用:
private Action<string> _foo;
public void Foo(Action<object> bar)
{
// This is fine...
_foo = bar;
}
现在当我们调用 _foo 时,我们必须传入一个字符串——但这没关系,因为我们已经用一个可以接受任何 object 的委托(delegate)对其进行了初始化。引用作为参数,所以我们恰好给它一个字符串也没关系。
所以基本上 Action<T>是逆变 - 而Func<T>是协变的:
Func<string> bar = ...;
Func<object> foo = bar; // This is fine
object x = foo(); // This is guaranteed to be okay
目前尚不清楚您要通过该操作做什么,所以很遗憾,我无法就如何解决此问题提供任何建议...
关于c# - Action 委托(delegate)、泛型、协变和逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6904805/
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我有一个rubyonrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来
我有以下类(class):classAlphabetattr_reader:letter_freqs,:statistic_letterdefinitialize(lang)@lang=langcaselangwhen:en@alphabet=('A'..'Z').to_a@letter_freqs={...}when:ru@alphabet=('А'..'Я').to_a.insert(6,'Ё')@letter_freqs={...}...end@statistic_letter=@letter_freqs.max_by{|k,v|v}[0]endendfoo=Alphabet.n
我正在尝试在我的Controller中测试新操作。目前它看起来像这样:Controllerdefnew@business=Business.new@business.addresses.buildend规范describe'GET#new'doit'assignsanewbusinessto@business'doget:newexpect(assigns(:business)).tobe_a_new(Business)endend我想测试“@business.addresses.build”这一行。我该怎么做?提前致谢! 最佳答案
我正在尝试升级到Rails4beta1,但遇到了一些问题。简而言之,这就是我的应用程序Controller的样子。classApplicationControllercaches_action在Rails4中移到了它自己的gem中,因此包含gem应该可以解决问题。gem"actionpack-action_caching",github:"rails/actionpack-action_caching"但是当我运行我的请求规范或在浏览器中访问该应用程序时,我收到此错误。app/controllers/application_controller.rb:3:in`':undefinedm
我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume