定义C#接口的隐式和显式转换

有没有办法编写基于界面的代码(即使用接口而不是类作为C#中接受和传递的类型),而不放弃使用隐式转换的东西?这里有一些示例代码 – 已经删除了很多,但这些是相关的部分。

 public class Game
 {
     public class VariantInfo
     {
         public string Language { get; set; }
         public string Variant { get; set; }
     }
 }

在ScrDictionary.cs中,我们有…

 public class ScrDictionary: IScrDictionary
 {
     public string Language { get; set; }
     public string Variant { get; set; }

     public static implicit operator Game.VariantInfo(ScrDictionary s)
     {
        return new Game.VariantInfo{Language=sd.Language, Variant=sd.Variant};
     }
 }

和界面…

 public interface IScrDictionary
 {
     string Language { get; set; }
     string Variant { get; set; }
 }

我想要使​​用IScrDictionary而不是ScrDictionary,但仍然能够将ScrDictionary隐式转换为Game.VariantInfo。此外,虽然可能有一个简单的方法来使这个工作,通过给IScrDictionary类型Game.VariantInfo的属性我的问题是更通用的:有没有办法在界面上定义转换或操作符重载? (如果没有,什么是适当的C#方式来维护这个功能,而不放弃面向对象的设计?)

您不能在界面上定义转换或操作符重载。由于接口是描述始终可用的成员的协议(作为对该接口的显式转换或作为公共成员),并且没有更多的依赖,您不能依赖于接口来包含任何内置的逻辑,例如如何投射或者操作符如何使用该界面执行。

您仍然可以从实现接口的抽象基类继承,并提供所需的逻辑,用于转换或操作符重载。这不违反接口导向的设计。不继承公共基类但实现接口的类仍然需要独立实现自己的隐式转换和运算符重载。如果您希望集中处理通常实现接口的类的逻辑,那么可以在C#3.0 / .NET Fx 3.5中使用扩展方法(或者在以前的版本中使用静态方法)。下面我用一个实用程序类和两个类,Foo和Bar,它们没有一个共同的祖先。他们共享包含效用函数Add的代码,所以你不必在这两个类中重复这个实现。

public interface IInterface
{
    int X { get; set; }
    int Y { get; set; }
}

public static class IInterfaceTHelper
{
    public static IInterface Add<T>(this IInterface a, IInterface b) 
        where T : new()
    {
        var ret = (IInterface)new T();
        ret.X = a.X + b.X;
        ret.Y = a.Y + b.Y;
        return ret;
    }
}

class Foo : IInterface
{
    public int X { get; set; }
    public int Y { get; set; }

    public static IInterface operator +(Foo a, IInterface b)
    {
        return a.Add<Foo>(b);
    }
}

class Bar : IInterface
{
    public int X { get; set; }
    public int Y { get; set; }

    public static IInterface operator +(Bar a, IInterface b)
    {
        return a.Add<Bar>(b);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo { X = 5, Y = 3 };
        var bar = new Bar { X = 3, Y = 5 };

        var result = foo + bar;
        Console.WriteLine(result.GetType().Name + " " + result.X + " " + result.Y);
        result = bar + foo;
        Console.WriteLine(result.GetType().Name + " " + result.X + " " + result.Y);

        Console.ReadLine();
    }
}

如果您的接口不仅仅包含违反合同设计的合同。

http://stackoverflow.com/questions/2776113/defining-implicit-and-explicit-casts-for-c-sharp-interfaces

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:定义C#接口的隐式和显式转换