Страницы

Поиск по вопросам

четверг, 2 января 2020 г.

Работа со вложенными Generic - типами

#c_sharp #классы #generics


Доброго времени суток.

Есть Класс.

/// 
/// Класс, являющийся "Номер Телефона".
/// 
/// Тип, в котором хранится Тип Номера Телефона.
// Кстати string не может быть ограничителем.

public class TelNumber where T : string 
{
    /// 
    /// ID Номер Телефона.
    /// 
    public int TelNumberID { get; set; }
    /// 
    /// Тип Номер Телефона.
    /// 
    public TypeTelNumber TypeTelNumber { get; set; }
}


Я хочу, чтобы тип телефона мог быть мог быть либо string, либо TypeTelNumber.

Пишу так:

/// 
/// Класс, являющийся "Номер Телефона".
/// 
/// Тип, в котором хранится Тип Номера Телефона.
public class TelNumber where T : string, TypeTelNumber
{
    /// 
    /// ID Номер Телефона.
    /// 
    public int TelNumberID { get; set; }
    /// 
    /// Тип Номер Телефона.
    /// 
    public T TypeTelNumber { get; set; }
}


Вопрос: Ругается на I, мол не такого типа (понятно и логично). Но как тогда сделать
задуманное?
    


Ответы

Ответ 1



Ваш код where T : string означает, что Т может быть только string, поскольку класс System.String объявлен как sealed. Чтобы скомпилировалось, достаточно объявить параметр I: public class TelNumber where T : string, TypeTelNumber { /// /// ID Номер Телефона. /// public int TelNumberID { get; set; } /// /// Тип Номер Телефона. /// public T TypeTelNumber { get; set; } } Но это не то, что вам нужно: в C# нет discriminated union-типов. Код where T : string, TypeTelNumber означает, что T должен быть одновременно и string, и TypeTelNumber. А поскольку string есть sealed, это означает, что ваш код не скомпилируется ни с каким типом. Имеет смысл объявить просто два отдельных класса, реализующих общий интерфейс. interface class ITelNumber { /// /// ID Номер Телефона. /// int TelNumberID { get; set; } /// /// Тип Номер Телефона. /// T TypeTelNumber { get; set; } } class StringTelNumber : ITelNumber { public int TelNumberID { get; set; } public string TypeTelNumber { get; set; } } class CustomTelNumber : ITelNumber> { public int TelNumberID { get; set; } public TypeTelNumber TypeTelNumber { get; set; } } А ограничения на типы налагать уже вашей бизнес-логикой, а не системой типов: в C# система типов такого (пока) не умеет.

Ответ 2



Как ответили в комментариях, пока задуманного сделать нельзя, ибо мой первый кусок означает И, а не ИЛИ. Вариант 1 Сделать, как в моем варианте. Вариант 2 Не ставить ограничений, т.е /// /// Класс, являющийся "Номер Телефона". /// /// Тип, в котором хранится Тип Номера Телефона. public class TelNumber { /// /// ID Номер Телефона. /// public int TelNumberID { get; set; } /// /// Тип Номер Телефона. /// public T TypeTelNumber { get; set; } } Во втором варианте появляется проблема, что я не могу контролировать какой тип используется для хранения типа. Ну и ладно(( Вариант 3 Сделать так, как предложил VladD в ответе. Именно это вариант я и использую.

Комментариев нет:

Отправить комментарий