Как предотвратить незаконное наследование ICloneable <T>в C #? - PullRequest
0 голосов
/ 22 мая 2018

У меня есть интерфейс:

public interface ICloneable<out T>
    where T : ICloneable<T>
{
    T Clone();
}

, который должен получить тип, реализующий этот интерфейс (как показано ниже).И я могу создать класс, который его реализует:

public class Class : ICloneable<Class>
{
    public Class Clone() { return (Class)MemberwiseClone(); }
}

Отлично!

Но любой может создать класс, который реализует ICloneable «неправильно». Существует ли способ предотвратить наследование, как показано ниже? (2 примера)

public class Other : ICloneable<Class>
{
    public Class Clone() { return new Class(); }
}

public class Other : Class, ICloneable<Class>
{
    public Class Clone() { return (Other)MemberwiseClone(); }
}

И разрешить наследование, как показано ниже?(любой из 2 примеров)

public class Other : ICloneable<Other>
{
    public Other Clone() { return (Other)MemberwiseClone(); }
}

public class Other : Class, ICloneable<Other>
{
    public Other Clone() { return (Other)MemberwiseClone(); }
}

1 Ответ

0 голосов
/ 22 мая 2018

Вы не можете перегружать класс, поэтому:

public class Other : Class {}
public class Other : Class, IC<Other> {}

Никогда не будет работать.

Теперь я собираюсь вытащить Джона Скита и показать, как вы могли бы сделать это, но затем отговорить вас от этого.Вы можете сделать что-то вроде этого:

public class CloneableOther : Class, ICloneable<Other> {  }
public class Other : CloneableOther
{

}    

public class CloneableFoo : Class, ICloneable<Foo> { }
public class Foo : CloneableFoo
{

}

То, что делает этот код, эффективно удаляет универсальный параметр из наследования.За исключением того, что Foo все еще может делать это: Foo : CloneableFoo, ICloneable<Other>, и теперь вам придется создавать два класса для каждого экземпляра ICloneable.

Это входит в это , почему вам это нужно в первую очередь?Это практика Foo : IInterface<Foo>, но нет способа ее применить.Лучше всего просто скопировать и вставить и быть уверенным, что класс соответствует.

Может быть, другой способ заключается в том, чтобы в конструкторе Class проверить, является ли тип ICloneable типом класса, и вызвать исключение, если это не так, иЭто может быть похоже на ошибку во время компиляции, если это сделано достаточно рано во время выполнения.

...