2011-04-21 49 views
3

我试图做类似如下:如何编写从接口到另一种类型的隐式转换?

public class SomeWrapper : ISomeWrapper{ 

    public static implicit operator ActualRec(ISomeWrapper someWrapper) 
     { 
      return ((SomeWrapper)someWrapper).SomeInfo; 
     } 
} 

但这个代码失败,他说: “无论是参数或返回类型的类型必须为SomeWrapper的”。

我了解编译说明的问题。但我需要这种类型转换b,因为在我的应用程序中,我使用ISomeWrapper作为变量,存储SomeWrapper实例。 (另外,SomeWrapper是唯一实现ISomeWrapper的类)。

如果ISomeWrapper接口与我在具体类中知道的类型有什么办法进行隐式转换?

编辑: 正如所有人所暗示的,在C#中不可能从接口进行隐式转换。

我需要这样做的原因是什么?我想允许(隐式地)给ISomeWrapper的用户调用需要ActualRec作为参数的方法,而不给予ISomeWrapper的用户访问ActualRec的方法/属性的权限。

例如, 如果我包括ISomeWrapper属性ActualRec然后ISomeWrapper的用户将能够调用方法提供ActualRec(喂,someWrapper.ActualRec.Dispose()),我不希望公开。

这就是尝试寻找隐式转换的原因。

另外,我不想在应用程序中使用SomeWrapper。

请建议是否有一些概念/模式来完成这项工作。

感谢您的关注。

+3

“SomeWrapper是唯一实现ISomeWrapper的类” - 即挥动着一个大红旗,上面写着“糟糕的代码味道”。如果只有一个类实现接口,那么接口的值是多少?随处使用课程。 – 2011-04-21 15:57:28

+0

@Eric:这不是没有意义的,因为我使用这个接口进行单元测试。 – 2011-04-22 12:33:21

回答

6

我会说你的设计存在缺陷。您从界面转换为具体类型,这使得界面的使用毫无意义。该接口是一种契约,通过该契约,实现类型将符合提供所需的一组服务。在你的例子中,SomeInfo属性没有在界面(契约)中定义?如果不是,你为什么试图使用界面进行投射?你应该使用SomeWrapper作为输入参数本身。

+0

我同意你的意见。设计看起来不太好。 请参阅我的问题描述中的编辑部分,我已经描述了采取这种方法的原因。 – 2011-04-22 12:50:09

2

C#不允许这样做,因为这样的功能很容易导致无法读取的代码,使其他开发人员眼花缭乱。尝试使用扩展方法代替:

public static class SomeWrapperExtensions 
{ 
    public static ActualRec ToActualRec(
     this ISomeWrapper wrapper) 
    { 
     return ((SomeWrapper)someWrapper).SomeInfo; 
    } 
} 

这可以让你做约定的方式,不会surprise其他开发商:

ActualRec rec = wrapper.ToActualRec(); 

注意,这还是如果脆弱的,但因为你不” t知道ISomeWrapper实际上是否代表SomeWrapper的实现。

+0

我希望存在一种隐式转换形式,它只能用于值被明确强制为目标类型的上下文中(例如作为赋值,或作为第n个参数传递给第n个参数不能采用的方法还要别的吗)。大多数涉及隐式转换*到*接口类型的令人眼花缭乱的情况都源于存在这种转换会导致非显而易见的过载选择的情况;这种行为几乎不限于接口。 – supercat 2013-09-02 21:35:45

6

这在C#中受到限制。参见下文。

http://msdn.microsoft.com/en-us/library/aa664464%28VS.71%29.aspx

类或结构允许声明从源类型S转换至T提供以下所有的都为真,目标类型:

...

S和T都不是对象或接口类型。

此外,

用户定义的转换不允许从转换或接口类型。 特别是,此限制可确保在转换为接口类型时不发生用户定义的转换,并且仅当转换的对象实际实现指定的接口类型时才转换为接口类型才能成功 。

相关问题