public class Base {
public Base(int x) { }
}
public class Derived : Base {
public Derived(string a, int x) : base(x) { }
}
Коснструктор при наследовании абстрактного класса
Код:
public abstract class Class<This> //Объявляем абстрактный класс Class<This>
where This: Class<This> //Объявляем, что тип This является производным от Class<This>
{
public Class(int x) //Объявляем поддержку конструктора с параметром int
{
}
public This Create(int x) //Задаем метод возвращающит тип This
{
return new This(x); //Создаем тип This // Ошибка(!)
}
}
where This: Class<This> //Объявляем, что тип This является производным от Class<This>
{
public Class(int x) //Объявляем поддержку конструктора с параметром int
{
}
public This Create(int x) //Задаем метод возвращающит тип This
{
return new This(x); //Создаем тип This // Ошибка(!)
}
}
И вот что непонятно: Почему строка return new This() вызывает ошибку? Ведь This является производным от Class<This> и должен поддерживать данный конструктор....
Если кто знает причину или как этого избежать - буду очень благодарен!
Цитата: sigmov
Почему строка return new This() вызывает ошибку? Ведь This является производным от Class<This> и должен поддерживать данный конструктор....
Он может не поддерживать этот конструктор. Контр пример:
Код:
Код:
This t = (This) Activator.CreateInstance(typeof(This), x);
Цитата: hardcase
Код:
This t = (This) Activator.CreateInstance(typeof(This), x);
Предложение хорошее. Но в силу приведенного вами же контрпримера оно теряет смысл :(
Да и скорость является критичным параметром.
Пришлось оставить реализацию "потомкам"
Код:
public abstract class Class<This> //Объявляем абстрактный класс Class<This>
where This : Class<This> //Объявляем, что тип This является производным от Class<This>
{
protected abstract This CreateThis(int x);
public Class(int x) //Объявляем поддержку конструктора с параметром int
{
}
public This Create(int x) //Задаем метод возвращающит тип This
{
return this.CreateThis(x); //Создаем тип This // Ошибка(!)
}
}
where This : Class<This> //Объявляем, что тип This является производным от Class<This>
{
protected abstract This CreateThis(int x);
public Class(int x) //Объявляем поддержку конструктора с параметром int
{
}
public This Create(int x) //Задаем метод возвращающит тип This
{
return this.CreateThis(x); //Создаем тип This // Ошибка(!)
}
}
Цитата: sigmov
Предложение хорошее. Но в силу приведенного вами же контрпримера оно теряет смысл :(
В .NET, к сожалению, нельзя накладывать обобщенные ограничения на конструкторы, я уже как-то отмечал этот факт на форуме (искать тему лениво). Но, все же, если семейство T-типов достаточно однородно, можно применить паттерн отложенной инициализации:
Код:
public interface IInitializable {
void Initialize(int x);
}
public class Container<T> where T : IInitializable, new() {
public T MakeInstance(int x) {
T obj = new T();
obj.Initialize(x);
return obj;
}
}
void Initialize(int x);
}
public class Container<T> where T : IInitializable, new() {
public T MakeInstance(int x) {
T obj = new T();
obj.Initialize(x);
return obj;
}
}
Код:
public abstract class Base<This>
where This : Base<This>
{
public delegate This ObjectCreator();
readonly ObjectCreator _creator;
protected Base(ObjectCreator object_creator)
{
_creator = object_creator;
}
public This Create()
{
return _creator();
}
}
class Derrived : Base<Derrived>
{
public Derrived(int x)
: base(() => new Derrived(x))
{
X = x;
}
public int X { get; private set; }
}
class Program
{
static void Main(string[] args)
{
var derrived = (new Derrived(123)).Create();
}
}
where This : Base<This>
{
public delegate This ObjectCreator();
readonly ObjectCreator _creator;
protected Base(ObjectCreator object_creator)
{
_creator = object_creator;
}
public This Create()
{
return _creator();
}
}
class Derrived : Base<Derrived>
{
public Derrived(int x)
: base(() => new Derrived(x))
{
X = x;
}
public int X { get; private set; }
}
class Program
{
static void Main(string[] args)
{
var derrived = (new Derrived(123)).Create();
}
}
Код:
public abstract class Base<This>
where This : Base<This>
{
protected Base(int x)
{
X = x;
}
public int X { get; private set; }
public abstract This Create();
}
class Derrived : Base<Derrived>
{
public Derrived(int x, int y)
: base(x)
{
Y = y;
}
public int Y { get; private set; }
public override Derrived Create()
{
return new Derrived(X, Y);
}
}
where This : Base<This>
{
protected Base(int x)
{
X = x;
}
public int X { get; private set; }
public abstract This Create();
}
class Derrived : Base<Derrived>
{
public Derrived(int x, int y)
: base(x)
{
Y = y;
}
public int Y { get; private set; }
public override Derrived Create()
{
return new Derrived(X, Y);
}
}