Может ли это быть сделано с помощью метода расширения? Тогда вы можете просто использовать интерфейс. Методы расширения являются хорошим способом добавления общей логики реализации к интерфейсу.
Это работает лучше всего для вас в основном говорят о IGenerator
(не конкретных типах) - поскольку расширение разрешения предпочитает типы - то есть FredsGenerator
может объявить сделанный на заказ метод Combine
, который (если вводим переменные как FredsGenerator
). Но это ничем не отличается от вашего примера, поскольку FredsGenerator
может повторно реализовать интерфейс, украдя реализацию:
using System;
interface IFoo {
void Bar();
}
abstract class FooBase {
public void Bar() { Console.WriteLine("Non-virtual; you can't override me!!!"); }
}
class FooImpl : FooBase, IFoo {
new public void Bar() { Console.WriteLine("mwahahahahah"); }
}
static class Program {
static void Main() {
IFoo foo = new FooImpl();
foo.Bar();
}
}
По крайней мере, при использовании метода расширения ваш код не может быть обманутым для запуска повторно реализованной версии; ваш код знает только о IGenerator
, поэтому only будет использоваться Generator.Combine
версия. Когда-либо.
Пример ( edit переработан по вашему примеру):
using System;
public interface IGenerator
{
// note: no Combine
object GenerateLolKThx();
}
public static class Generator
{
///<summary>
/// Combines two generators; performs magic as well
/// </summary>
public static IGenerator Combine(this IGenerator current, IGenerator next)
{
// do stuff that I really don't want implementors to try and do
// because its complex and can result in bad juju if done wrong
Console.WriteLine("Super secret logic here...");
// and prove we have access the the objects...
Console.WriteLine(current.GenerateLolKThx());
Console.WriteLine(next.GenerateLolKThx());
return next; // just for illustration
}
}
class MyGenerator : IGenerator
{
private readonly object state;
public MyGenerator(object state) {this.state = state;}
public object GenerateLolKThx() { return state; }
}
public static class Program
{
static void Main()
{
IGenerator foo = new MyGenerator("Hello"),
bar = new MyGenerator("world");
IGenerator combined = foo.Combine(bar);
}
}