c# - 为 C# 接口(interface)定义隐式和显式强制转换

标签 c# interface

有没有一种方法可以在 C# 中编写基于接口(interface)的代码(即使用接口(interface)而不是类作为接受和传递的类型)而不放弃使用隐式转换之类的东西?下面是一些示例代码 - 删除了很多,但这些是相关部分。

 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 隐式转换为 游戏.VariantInfo。此外,虽然可能有一种简单的方法可以通过为 IScrDictionary 提供 Game.VariantInfo 类型的属性来完成这项工作,但我的问题更笼统:有没有办法在接口(interface)上定义强制转换或运算符重载?(如果不是,在不放弃面向接口(interface)的设计的情况下维护此功能的正确 C# 方法是什么?)

最佳答案

您不能在接口(interface)上定义强制转换或运算符重载。由于接口(interface)是描述成员的契约,这些成员将始终可用(作为对该接口(interface)的显式转换或作为公共(public)成员),仅此而已,您不能依赖接口(interface)来包含任何类型的内置逻辑,例如如何转换或者运算符(operator)将如何使用该界面执行操作。

您仍然可以从实现接口(interface)并提供转换或运算符重载所需逻辑的抽象基类继承。这并不违反面向接口(interface)的设计。不继承公共(public)基类但实现接口(interface)的类仍然需要独立实现它们自己的隐式转换和运算符重载。如果您希望集中处理通常实现接口(interface)的类的逻辑,您可以在 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();
    }
}

如果您的界面不仅仅包含违反契约设计的契约。

关于c# - 为 C# 接口(interface)定义隐式和显式强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2776113/

相关文章:

c# - 如何让Tesseract OCR以句子形式输出单词?

c# - XAML 绑定(bind)到带有参数的静态方法

c# - WPF 的自动完成组合框

c# - Umbraco 6 - 读取中央配置设置的 "correct"方式是什么?

linux - Perl 检查网络接口(interface)是否启动(linux)

c# - 用于监视目录中文件更改的 WCF 服务

Javascript:更改滚动条中可滚动元素句柄的大小

c++ - 代表类型的变量?运行时继承?

Angular 6 类型错误 : Cannot read property 'e4b7...f' of undefined

delphi - Delphi 中 Form 分发与其生命周期相关的接口(interface)对象的安全方法?