C# динамически создавать экземпляры Type из Enum - PullRequest
0 голосов
/ 02 апреля 2020

Я C# новичок. Я надеюсь, у вас есть терпение со мной. Допустим, у меня есть перечисление

public enum Dogs
{
    Terrier,
    Poodle,
    Pitbull,
}

и некоторые классы собак

public class Terrier {
}

public class Poodle {
}

public class Pitbull {
}

И я по какой-то причине хочу динамически создавать каждый из классов по их типам (значениям перечисления),

        foreach(Dogs d in Enum.GetValues(typeof(Dogs)))
        {
            // d myDog = new d();
            // "...is a variable but is used like a type"
        }

Я также пытался с

var myDog = Activator.CreateInstance(d);
// "...cannot convert from namespace.Dogs to System.Type"

Ответы [ 3 ]

4 голосов
/ 02 апреля 2020

Если вы действительно этого хотите:

(typeof(Dogs)).Assembly.CreateInstance(d.ToString());
2 голосов
/ 02 апреля 2020

Не используйте перечисление для этого. Более разумным решением является массив типов:

private static Type[] dogs =
{
    typeof(Terrier),
    typeof(Poodle),
    typeof(Pitbull),
}

Тогда вы все равно можете go над всеми ними:

foreach (Type type in dogs)
{
    Object dog = Activator.CreateInstance(type);
}

Хотя, если только вы не используете .ToString() на это, возможно, вы захотите дать этим классам общий интерфейс или суперкласс для наследования (как rfmodulator также сказал в своем ответе), чтобы вы могли фактически вызывать функции для результирующих объектов. Если все три наследуются от суперкласса Dog, что позволяет им использовать общий метод Bark(), вы можете по крайней мере сделать что-то вроде этого:

public abstract class Dog
{
    String Bark();
}

public class Terrier : Dog
{
    public override String Bark() { return "Woof!"; }
}

public class Poodle : Dog
{
    public override String Bark() { return "Yap"; }
}

public class Pitbull : Dog
{
    public override String Bark() { return "Whuff!"; }
}

... так что вы действительно сможете получить что-то полезное из ваших созданных объектов:

foreach (Type type in dogs)
{
    Dog dog = (Dog)Activator.CreateInstance(type);
    Console.WriteLine(dog.Bark());
}
1 голос
/ 02 апреля 2020

Dogs.Terrier - это нечто иное, чем Terrier.

Вот как вы можете сделать что-то, как вы описываете:

Для простоты я собираюсь сделать все классы реализуют общий интерфейс, IDog:

public interface IDog { }

public class Terrier : IDog
{
}

public class Poodle : IDog
{
}

public class Pitbull : IDog
{
}

Теперь мы можем сделать это:

IDog dog;
foreach (Dogs d in Enum.GetValues(typeof(Dogs)))
{
    switch (d)
    {
        case Dogs.Terrier:
            dog = new Terrier();
            break;
        case Dogs.Poodle:
            dog = new Poodle();
            break;
        case Dogs.Pitbull:
            dog = new Pitbull();
            break;
        default:
            throw new Exception("no such dog!");
    }

    Debug.WriteLine($"dog is {dog.GetType()}");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...