与普通的不工作的接口隐含的运营商 [英] implicit operator with generic not working for interface

查看:121
本文介绍了与普通的不工作的接口隐含的运营商的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我主要有以下几个类(例如在 C#中创建泛型类的隐式转换

I basically have the following class (example found on C# creating an implicit conversion for generic class?).

class MyClass<T>
{
  public MyClass(T val)
  {
     Value = val;
  }

  public T Value { get; set; }

  public static implicit operator MyClass<T>(T someValue)
  {
     return new MyClass<T>(someValue);
  }

  public static implicit operator T(MyClass<T> myClassInstance)
  {
     return myClassInstance.Value;
  }
}

一个可以做

MyClass<IFoo> foo1 = new Foo();
MyClass<Foo>  foo2 = new Foo();

//But not
MyClass<IFoo> foo3 = (IFoo)new Foo();



试图做这样的事情。

The real issue occurs when trying to do something like

void Bar(IFoo foo)
{
    Bar2(foo);
    //What should be the same as
    Bar2<IFoo>(new MyClass<IFoo>(foo));
}

void Bar2<T>(MyClass<T> myClass)
{
     //Do stuff
}

我怎么能重构MyClass的所以这将是可能的时候只有接口是已知对象的工作?

How could I refactor MyClass so it would be possible to work with objects when only the interface is known?

推荐答案

简短的回答:

用户定义的隐式转换不会在接口上工作。不要试图使它工作。 。找到另一个解决您的类型系统的问题。

User-defined implicit conversions do not work on interfaces. Don't try to make it work. Find another solution to your type system problem.

龙答:

这是C#的慎重决定设计团队。其原理是,当你正在参与要保持参照标识的接口转换;你是想询问的标识的实现接口的对象,而不是试图创建一个具有类似性质相似的对象。

This is a deliberate decision of the C# design team. The principle is that when you are making a conversion involving an interface you want to preserve referential identity; you are asking about the identity of the object that implements the interface, not trying to create a similar object that has similar properties.

较大这里的原则是,一个用户定义的转换不应该更换内置转换。但是,由于几乎所有的类都可以被继承,而子类可以只实现任何接口,它是很难知道的静态的涉及的接口给定用户定义的转换是否会被替换内置了转换。

The larger principle here is that a user-defined conversion should not replace a built-in conversion. But since almost any class can be subclassed, and that subclass can implement just about any interface, it is very hard to know statically whether a given user-defined conversion involving an interface might be replacing a built-in conversion.

FYI这是规范的一个特别棘手位和C#编译器在这里有一些错误。我怀疑你的案件之一以上利用这些缺陷的;事实上,也有现实世界的方案,其中这样做是从固定的错误阻止我。

FYI this is a particularly tricky bit of the specification, and the C# compiler has some bugs here. I suspect that one of your cases above takes advantage of these bugs; the fact that there are real-world programs which do so is what prevented me from fixing the bugs.

的错误大多是这个功能的结果被仿制药之前设计的,再没有重新设计后,充分的仿制药推出了很多不可预见的并发症。

The bugs are mostly a consequence of this feature being designed before generics, and then not redesigned sufficiently after generics introduced many unforeseen complications.

有关详细信息,请参阅我广泛征求意见的,特别是对位标记故意SPEC侵犯该描述与接口的转换问题。

For details, see my extensive comments here, particularly the bits marked DELIBERATE SPEC VIOLATION that describe problems with interface conversions.

的https: //github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/UserDefinedImplicitConversions.cs

正如你所看到的,这个文件是不到一千行代码,大概一半以上的意见多。精心研究,并与语言球队拿到这些语义多次讨论过了的的整理出来。一旦你在编译器中犯了一个错误,你经常彻底十年后了解它,然后它供奉永远这样在升​​级时不会打破一个客户。有许多对象教训语言设计者在C#中如何搞砸规范的这个不起眼的一部分。

As you can see, this file is less than a thousand lines long, and probably more than half comments. It took weeks of careful research and many discussions with the language team to get these semantics sorted out. Once you make a mistake in a compiler, you often have to understand it thoroughly a decade later, and then enshrine it forever so as to not break a customer on upgrade. There are many object lessons to language designers in how C# messed up this obscure part of the specification.

我怎么能重构MyClass的所以它会可能当只有接口是已知对象的工作?

How could I refactor MyClass so it would be possible to work with objects when only the interface is known?

不要轻易尝试。铸造界面参考的实际的运行时类型,然后从那里工作。或显式的,而不是由隐式转换产生所需类型的一个实例。不要试图玩隐式转换和接口的游戏;它不会工作搞好。

Don't try. Cast the interface reference to the actual runtime type and then work with it from there. Or create an instance of the desired type explicitly, rather than by implicit conversion. Don't try to play games with implicit conversions and interfaces; it will not work out well.

这篇关于与普通的不工作的接口隐含的运营商的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆