简体   繁体   English

使用变量作为类型并实例化它

[英]Use variable as type and instantiate it

First of all, I want to say that I'm new to C#, so this question may seem completely off track. 首先,我想说我是C#的新手,所以这个问题似乎完全偏离了轨道。

I have a set of enumerables called ShapeType: 我有一组名为ShapeType的枚举:

Cube, Sphere, Rectangle, Ellipse

And a method to return a random value from the enumerables: 以及从枚举中返回随机值的方法:

private static ShapeType GetRandomShape()
{
    Array values = Enum.GetValues(typeof(ShapeType));
    Random random = new Random();
    ShapeType randomShape = (ShapeType)values.GetValue(random.Next(values.Length));
    return randomShape;
}

Every enumerable has a corresponding concrete class. 每个可枚举的都有相应的具体类。 And the question I'm wondering about is if you can instantiate a class by using the random enumerable value randomShape, kind of like this: 我想知道的问题是,如果你可以使用随机可枚举值randomShape来实例化一个类,有点像这样:

private static Shape GetRandomShape()
{
    Array values = Enum.GetValues(typeof(ShapeType));
    Random random = new Random();
    ShapeType randomShape = (ShapeType)values.GetValue(random.Next(values.Length));
    Shape shape = new randomShape(); // *Here use the randomShape-variable as type*
    return shape;
}

Is this possible or is it just wishful thinking? 这可能还是只是一厢情愿的想法?

You can use a dictionary to retrieve a factory function for every value of the enum: 您可以使用字典为枚举的每个值检索工厂函数:

static readonly Dictionary<ShapeType, Func<Shape>> _factoryLookup = new Dictionary<ShapeType, Func<Shape>>
{
    [ShapeType.Cube] = () => new Cube(),
    [ShapeType.Ellipse] = () => new Ellipse(),
    [ShapeType.Rectangle] = () => new Rectangle(),
    [ShapeType.Sphere] = () => new Sphere(),
};

static readonly Random random = new Random();

private static Shape GetRandomShape()
{
    Array values = Enum.GetValues(typeof(ShapeType));
    ShapeType randomShape = (ShapeType)values.GetValue(random.Next(values.Length));
    Func<Shape> factory = _factoryLookup[randomShape];
    Shape shape = factory();
    return shape;
}

You need to use factory method pattern : 您需要使用工厂方法模式

public class Shape {}

public class Cube : Shape {}

public class Sphere : Shape {}

public class Rectangle : Shape {}

public class Ellipse : Shape {}

public Shape randomShape(ShapeType shapeType)
{
    switch(shapeType)
    {
         case ShapeType.Cube:
         return new Cube();
         ...
    }
}

Create a Dictionary, with enumvalue as key, and type as value. 使用enumvalue作为键创建一个Dictionary,并键入value。

Dictionary<ShapeType, Type> dic = new Dictionary<ShapeType, Type>();
dic.Add(ShapeType.Cube, typeof(Cube));

// ...

private static Shape GetRandomShape()
{
    Array values = Enum.GetValues(typeof(ShapeType));
    Random random = new Random();
    ShapeType randomShape = (ShapeType)values.GetValue(random.Next(values.Length));
    Shape shape = Activator.CreateInstance(dic[randomShape]); // *Here use the randomShape-variable as type*
    return shape;
}

Instead of 代替

enum ShapeType { Cube, Sphere, Rectangle, Ellipse }

You can use something like 你可以使用类似的东西

abstract class Figure
{
    protected int id;

    public static implicit operator int(Figure figure) => figure.id;
    public static implicit operator Figure(int value) => Figures().First(figure => figure.id == value);

    protected Figure(int id)
    {
        this.id = id;
    }

    public static Cube Cube { get; } = new Cube(1);
    public static Sphere Sphere { get; } = new Sphere(2);

    public static IEnumerable<Figure> Figures()
    {
        yield return Cube;
        yield return Sphere;
    }

    public override string ToString() => this.GetType().ToString();
}

class Cube : Figure
{
    public Cube(int id) : base(id) { }
}
class Sphere : Figure
{
    public Sphere(int id) : base(id) { }
}

this will let you to do something like: 这将让你做类似的事情:

Console.WriteLine((object)(Figure)1); // Cube
Console.WriteLine((object)(Figure)2); // Sphere

I am using such approach in many places instead of enum , which is often not sufficient (as it needs to hold extra information than just name and int ). 我在许多地方使用这种方法而不是enum ,这通常是不够的(因为它需要保存额外的信息,而不仅仅是名称和int )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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