【问题标题】:Use variable as type and instantiate it使用变量作为类型并实例化它
【发布时间】:2017-05-04 20:50:19
【问题描述】:

首先,我想说我是 C# 新手,所以这个问题可能看起来完全偏离了轨道。

我有一组称为 ShapeType 的枚举:

Cube, Sphere, Rectangle, Ellipse

还有一种从枚举中返回随机值的方法:

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;
}

每个可枚举都有一个对应的具体类。我想知道的问题是你是否可以通过使用随机可枚举值 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;
}

这是可能的还是只是一厢情愿?

【问题讨论】:

  • “每个可枚举都有一个对应的具体类” - 您可以使用字典将枚举值映射到相应的类型/实例。另一种选择是根本不使用枚举,而是隐含到int 转换(现在使用枚举值)。

标签: c#


【解决方案1】:

您可以使用字典为枚举的每个值检索 factory 函数:

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;
}

【讨论】:

    【解决方案2】:

    你需要使用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();
             ...
        }
    }
    

    【讨论】:

    • 我认为不是这个问题。
    【解决方案3】:

    创建一个字典,以枚举值为键,类型为值。

    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;
    }
    

    【讨论】:

      【解决方案4】:

      代替

      enum ShapeType { Cube, Sphere, Rectangle, Ellipse }
      

      你可以使用类似的东西

      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) { }
      }
      

      这将使您可以执行以下操作:

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

      我在很多地方都在使用这种方法,而不是 enum,这通常是不够的(因为它需要保存额外的信息,而不仅仅是名称和 int)。

      【讨论】:

        猜你喜欢
        • 2014-08-24
        • 1970-01-01
        • 1970-01-01
        • 2016-09-03
        • 1970-01-01
        • 1970-01-01
        • 2013-04-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多