我正在使用多态来使用基本形状类
定义不同的形状类public class Shape
{
}
class Circle : Shape
{
}
class Triangle : Shape
{
}
在运行时,我根据变量" thisShape"
创建一个类的实例Shape myShape;
if (thisShape == "Circle") myShape = new Circle();
if (thisShape == "Triangle") myShape = new Triangle();
这有效,但我觉得应该有办法避免使用多个if。
# Pseudo code
Shape myShape = new {thisShape}();
动态实例是否有单行语法?
答案 0 :(得分:2)
理论上有,但我不推荐它:你可以使用反射。
Type shapeType = Assembly.GetExecutingAssembly().GetType(thisShape);
Shape myShape = (Shape)Activator.CreateInstance(shapeType);
编辑:
这带来了许多问题,包括性能和安全问题。 有更好的方法来处理这些问题,例如抽象工厂设计模式。
答案 1 :(得分:1)
您应该将其封装到SimpleShapeFactory
。
如果您不想撰写if
或case
,可以创建自己的Attribute
(让它命名为ShapeNameAttribute
):
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
sealed class ShapeNameAttribute : Attribute
{
#region Constructors
public ShapeNameAttribute(string name)
{
Name = name;
}
#endregion // Constructors
#region Properties
public string Name
{
get;
set;
}
#endregion // Properties
}
然后使用此属性标记所有类:
[ShapeName("Shape")]
public class Shape
{
}
[ShapeName("Circle")]
class Circle : Shape
{
}
[ShapeName("Triangle")]
class Triangle : Shape
{
}
并像这样创建SimpleShapeFactory
:
static class SimpleShapeFactory
{
#region Private Members
public static readonly Type[] _shapes = new Type[]
{
typeof(Shape),
typeof(Circle),
typeof(Triangle)
};
#endregion // Private Members
#region Methods
/// <summary>
/// Creates shape by it's name
/// </summary>
/// <param xmlName="name">Name of the shape</param>
/// <returns>Created shape</returns>
public static Shape Create(string name)
{
foreach(var shape in _shapes)
{
var attribute = (ShapeNameAttribute)shape.GetCustomAttributes(typeof(ShapeNameAttribute), true)[0];
if(attribute.Name == name)
{
return (Shape)Activator.CreateInstance(shape);
}
}
throw new ArgumentException("Invalid name");
}
#endregion // Methods
}
如果您不想在SimpleShapeFactory
中定义允许的类型,当然可以使用反射来确定它们,但