繁体   English   中英

C#4会允许“动态铸造”吗?如果没有,C#应该支持吗?

[英]Will C#4 allow “dynamic casting”? If not, should C# support it?

我不是指将一个较低的接口或基类转换为更多派生类的意义上的动态转换,我的意思是采用我创建的接口定义,然后动态地向该接口转换一个不是从该接口派生的不同对象接口但支持所有呼叫。

例如,

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = (dynamic<IMyInterface>)myTextBox;

这可以在编译时针对已知类型实现,而运行时针对使用dynamic声明的实例实现。 接口定义是已知的,类型(在此示例中)也是如此,因此编译器可以确定对象是否支持接口定义的调用,并为我们执行一些魔术以进行转换。

我的猜测是C#4不支持这个(我无法找到它的引用),但我想知道肯定。 如果不是,我想讨论它是否应该包含在该语言的未来变体中,以及支持和反对的原因。 对我来说,似乎是一个很好的补充,可以在代码中实现更大的多态性,而无需创建全新的类型来包装现有的框架类型。

更新
为了避免有人指责我抄袭,我不知道Jon Skeet已经提出过这个问题 但是,很高兴知道我们想到了非常相似的语法,这表明它至少可能是直观的。 与此同时,“有一个独创性的想法”仍然在我的清单上再次出现。

我认为Jon Skeet有这样一个提议( http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx ),但到目前为止,我还没有听说过C#4.0会有它。

我认为这有问题。 您正在引入两个未耦合的类之间的耦合。

请考虑以下代码。

public interface IFoo
{
   int MethodA();
   int MethodB();
}

public class Bar
{
   int MethodA();
   int MethodB();
}

public class SomeClass
{
   int MethodFoo(IFoo someFoo);
}

那么这应该合法吗?

int blah = someClass.MethodFoo((dynamic<IFoo>)bar);

看起来它应该是合法的,因为编译器应该能够动态地将bar键入为实现IFoo的东西。

但是,此时您通过在代码的完全独立部分中调用来耦合IFoo和Bar。

如果您编辑Bar因为它不再需要MethodB,则突然someClass.MethodFood不再起作用,即使Bar和IFoo不相关。

同样,如果将MethodC()添加到IFoo,您的代码将再次中断,即使IFoo和Bar表面上不相关。

事实是,虽然这在你不能控制的对象之间存在相似性的特定情况下会很有用,但是有一个原因是接口必须显式地附加到对象上,原因是编译器可以保证对象实现它。

开源框架Impromptu-Interface使用C#4和dlr完成此操作。

using ImpromptuInterface;

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = myTextBox.ActLike<IMyInterface>();

由于它使用dlr,因此它也可以与ExpandoObject和DynamicObject一起使用。

C#不需要支持它,因为它可以作为库非常干净地实现。

我已经看过三到四个单独的实现(我在找到之前就开始自己编写一个)。 这是我见过的最彻底的治疗方法:

http://bartdesmet.net/blogs/bart/archive/2008/11/10/introducing-the-c-ducktaper-bridging-the-dynamic-world-with-the-static-world.aspx

一旦DLR集成到运行时,它可能会更容易实现。

因为给定接口的包装器/转发器类可以生成一次然后被缓存,然后一个未知类型的给定对象可以被包装一次,所以调用站点的缓存有很多空间,所以性能应该是优秀。

相比之下,我认为dynamic关键词是一种语言特征,而且是一个非常复杂的关键词,它是一种不必要的,可能是灾难性的题外话,用于以前有一种非常清晰的静态打字哲学的语言,这使得它显而易见未来改进的方向。 他们应该坚持这一点,并使类型推断更好,更好,直到打字变得更加隐形。 有很多领域他们可以在不破坏现有程序的情况下改进语言,但他们却没有,仅仅是由于资源限制(例如var不能在更多地方使用的原因是因为他们必须重写编译器,他们没有时间)。

他们仍然在C#4.0(方差功能)中做得很好,但还有很多其他方法可以使类型系统在编译时检测问题时更智能,更自动,更强大。 相反,我们基本上得到了一个噱头。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM