Как разрешить универсальному классу иметь себя в качестве типа и обязательного свойстваC#

Место общения программистов C#
Ответить
Anonymous
 Как разрешить универсальному классу иметь себя в качестве типа и обязательного свойства

Сообщение Anonymous »

У меня есть общий класс для «общего» узла дерева следующим образом (упрощенно):

Код: Выделить всё

public class GeneralTreeNode
{
public virtual GeneralTreeNode? Parent { get; set; }
public virtual List Children { get; set; } = new List();
public virtual V Value { get; set; }

public GeneralTreeNode(V value, GeneralTreeNode? parent = null)
{
Value = value;
Parent = parent;
}

//public GeneralTreeNode() { Value = (V)this; }
// (not allowed: Cannot convert...)

public virtual GeneralTreeNode AddChild(V childValue)
{
var childNode = new GeneralTreeNode(childValue, this);
Children.Add(childNode);
return childNode;
}
}
Иногда я буду использовать этот класс как типичный контейнер: Node содержит содержимое узла или указывает на него через свойство Value. Это работает так, как и ожидалось.
Однако иногда мне также хочется использовать его там, где объект Content фактически наследует класс GeneralTreeNode, чтобы свойство Value указывало на него. Причина этого в том, что эти наследующие классы будут добавлять дополнительные указатели/ссылки на другие экземпляры того же класса, и им необходимо знать и иметь доступ к своим указателям и структуре GeneralTreeNode. (В отличие от типичного «содержащегося» класса, который не знает своего контейнера и внешней структуры).
Проблема в том, что я продолжаю получать ошибки, связанные с требованиями для установки/инициализации свойства Value. Вот простой пример:

Код: Выделить всё

// Example "integrated" use:
public class IntegratedValueNode : GeneralTreeNode
{
public int whatever { get; set; } = 0;

//public IntegratedValueNode() { Value = this; }
// (not allowed: No argument corresponds to the required formal parameter...)

//public IntegratedValueNode() : base(this) { }
// (not allowed: 'this' not available)
}
Приведенные выше комментарии к коду показывают различные вещи, которые я пытался решить, но ни одна из них не сработала, и без них он не будет компилироваться («Нет аргумента соответствует требуемому формальному параметру...»).
Я почти уверен, что раньше я мог это сделать (около 2010 года?) до того, как C# начал навязывать различные критерии «необнуляемых объектов», которые требуют, чтобы свойство было инициализировано базовым классом, прежде чем оно попадет в наследование конструктор класса.
Есть ли простой способ сделать это без необходимости обращаться к интерфейсу или делать свойство обнуляемым? Я не хочу делать значение обнуляемым, потому что оно никогда не является нулевым после инициализации, и я не хочу навязывать ложные проверки нуля для всего кода, который будет иметь к нему доступ. Я использую VS2022.

ПРИМЕЧАНИЕ. Предложение @shingo вызвать базовый конструктор с использованием null в качестве параметра сработало, но я не пробовал, потому что мне никогда не приходило в голову, что компилятор позволит использовать null в этот момент для параметра и свойства, не допускающего значения NULL.

Подробнее здесь: https://stackoverflow.com/questions/798 ... d-property
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»