Вы не можете определить трансляции или перегрузку оператора на интерфейсах. Поскольку интерфейс - это контракт, который описывает элементы, которые всегда будут доступны (либо как явное приведение к этому интерфейсу, либо как публичные члены), и не более того вы не можете полагаться на интерфейсы, чтобы содержать какую-либо встроенную логику, например, как делать или как операторы будут работать с этим интерфейсом.
Вы все еще можете наследовать от абстрактного базового класса, который реализует интерфейс и предоставляет логику, необходимую для бросков или перегрузки оператора. Это не нарушает ориентированный на интерфейс дизайн. Классы, которые не наследуются от общего базового класса, но реализуют интерфейс, по-прежнему должны самостоятельно реализовать свои собственные неявные броски и перегрузки операторов. Если вы хотите централизовать логику работы с классами, которые обычно реализуют интерфейс, вы можете сделать это в 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();
}
}
Если ваши интерфейсы содержат больше, чем просто контракты, которые будут нарушать дизайн по контракту.