У меня есть неуниверсальный интерфейс к общей группе классов. У меня есть метод, который использует ковариацию для возврата строго типизированного экземпляра в классе, полученном из абстрактной реализации неуниверсальной группы классов.
Так что в основном с этой настройкой у меня есть несколько классов, например ActualThing1
и ActualThing2
. Эти классы имеют метод Clone
, который возвращает строго типизированный клон самого себя.
Ниже показано, как я структурировал интерфейс и классы. Я не уверен, что это правильно.
Обычно у меня вообще не было бы не универсального абстрактного класса. Но это необходимо, потому что есть ситуация, когда я должен что-то делать с дочерними объектами, ссылаясь на внутренний метод _SomethingNeededInternally
. Это не может быть сделано с помощью интерфейса, поскольку он защищен, и при этом это не может быть сделано из общего класса, так как дочерние элементы могут быть не того же типа (они могут быть другого типа, производного от интерфейса). Следовательно, неуниверсальный базовый класс Something
.
Это работает, но для меня не совсем понятна явная реализация ISomething.Clone
, которая необходима в моем абстрактном Something
классе. Он должен быть там, но не должен быть реализован, так как я хочу, чтобы эта реализация была перенесена в общий класс, производный от него. Но нет такого синтаксиса как abstract ISomething ISomething.Clone()
.
Но этот код (где исключение - throw) не может быть выполнен, не так ли, поскольку у меня нет каких-либо неуниверсальных реализаций этого объекта?
Думаю, мне интересно, есть ли лучший способ сделать это, потому что это кажется неправильным. То есть я зависел от того факта, что неуниверсальный класс никогда не создается из интерфейса, что пахнет забавно.
public interface ISomething
{
// ...
ISomething Clone();
}
public abstract class Something: ISomething
{
ISomething ISomething.Clone()
{
throw new Exception("This should not be happening");
}
protected int _SomethingNeededInternally;
}
public abstract class Something<T>: Something, ISomething where T: ISomething, new()
{
public abstract T Clone();
ISomething ISomething.Clone()
{
return Clone();
}
}
public interface IActualThing {} // this could be any interface
public class ActualThing: Something<ActualThing>, IActualThing
{
public override ActualThing Clone()
{
return new ActualThing(); // do cloning here
}
}