简体   繁体   中英

C# Limiting Generic types in RunTime

I need to limit what can I put in the constructor in RunTime. I have easy classes:

    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());

    }
}

Is there any way user can say in RunTime "Type T can be only human" or "Type T can be only animal.". So if the user (for example in switch) says "Type T can be only human", then trying to create constructor, where Type T is animal will result in error.

Or if the user says "Type T can be only animal" then trying to create constructor, where Type T is human will results in error.

Another example: User says: "Type T can only be Animal":

Then doing: Generics<Human> human = new Generics<Human>(); will result in error.

Or Of course, if the user says "Type T can only be Human", this will lead to the error:

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

I don't know if this is possible, but if you have a solution I will be very glad. Thank you.

You can constraint the method or just check what is type of given 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);
            }
        }
    }

Since you want to limit generics at runtime , then I suppose you also want the error to be a runtime error, ie exception.

Declare a property/field somewhere, like this:

public Type TypeMustBe { get; set; }

At runtime, to say that "T must be Animal ", you do:

TypeMustBe = typeof(Animal);

Likewise, to say that "T must be Human ", you do:

TypeMustBe = typeof(Human);

In the constructor, you do this:

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

But I think this kind of loses the point of generics. Maybe rethink your design?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM