C # Ограничение универсальных типов в RunTime - PullRequest
0 голосов
/ 18 ноября 2018

Мне нужно ограничить то, что я могу поместить в конструктор в RunTime.У меня есть простые занятия:

    class Human
{
    public string Name { get; set; } = "John";
    public int Age { get; set; } = 20;
    public bool IsAlive { get; set; } = true; 

    public override string ToString()
    {
        return $"Name: {Name}, Age: {Age}, Is alive: {IsAlive}";
    }
}


    class Animal
{
    public string Type { get; set; } = "Bat";
    public int Weight { get; set; } = 33;
    public bool IsAlive { get; set; } = true;

    public override string ToString()
    {
        return $"Type: {Type}, Weight: {Weight}, Is alive: {IsAlive}";
    }
}



    class Generics<T> where T : class, new()
{
    public Generics()
    {
        T type = new T();
        Console.WriteLine(type.GetType());
        Console.WriteLine(type.ToString());

    }
}

Есть ли способ, которым пользователь может сказать в RunTime: «Тип T может быть только человеком» или «Тип T может быть только животным».Поэтому, если пользователь (например, в switch) говорит: «Тип T может быть только человеком», то попытка создать конструктор, где тип T является животным, приведет к ошибке.

Или, если пользователь говорит «Тип T может быть только животным», то попытка создать конструктор, где тип T является человеком, приведет к ошибке.

Другой пример: пользователь говорит: «Тип Tможет быть только Животное ":

Тогда выполнение: Generics<Human> human = new Generics<Human>(); приведет к ошибке.

Или, конечно, если пользователь говорит" Тип T может быть только человеком ", это приведет кошибка:

Generics<Animal> animal = new Generics<Animal>();

Я не знаю, возможно ли это, но если у вас есть решение, я буду очень рад.Спасибо.

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Так как вы хотите ограничить генерики в время выполнения , тогда я предполагаю, что вы также хотите, чтобы ошибка была время выполнения ошибка, т.е. исключение.

Объявление свойства/ поле где-то, как это:

public Type TypeMustBe { get; set; }

Во время выполнения, чтобы сказать, что "T должно быть Animal", вы делаете:

TypeMustBe = typeof(Animal);

Аналогично, чтобы сказать, что "Tдолжно быть Human ", вы делаете:

TypeMustBe = typeof(Human);

В конструкторе вы делаете это:

if (typeof(T) != TypeMustBe) {
    throw new Exception($"T must be {TypeMustBe}!");
}

Но я думаю, что этот вид теряет смысл обобщений.Может быть, переосмыслить свой дизайн?

0 голосов
/ 18 ноября 2018

Вы можете ограничить метод или просто проверить, какой тип задан T

  public class Creator
        {
            public static T CreateHuman<T>()
                where T : Human, new()
            {
                return new T();
            }

            public static T CreateAnimal<T>()
                where T : Animal, new()
            {
                return new T();
            }

            public static T Create<T>()
                where T : class, new()
            {

                switch (typeof(T))
                {
                    case Type t when t == typeof(Human):
                        //throw new Exception("Type can be only Animal");
                        break;
                    case Type t when t == typeof(Animal):
                        //throw new Exception("Type can be only Human");
                        break;

                }

                return default(T);
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...