C#接口实现中的不同类型

深红怪胎

我真的很难获得这个权利,但我会尽力解释我的观点。

说我有这个:

    List<IShape> Shapes = new List<IShape>();

    public interface IShape {
       dynamic shapeAttributes { get; set; }
    };

    public struct SquareAttributes {
      float sizeOfSide;
    };

    public struct CircleAttributes {
      float radius
    };
    
    public class Square : IShape {
      SquareAttributes shapeAttributes { get; set; }
    };

    public class Circle : IShape {
      CircleAttributes shapeAttributes { get; set; }
    };

    Shapes.Add(new Square());
    Shapes.Add(new Circle());
    

我如何使这种情况发挥作用?这里 IShape 中的“动态”关键字在 Square 和 Circle 中实现时没有解决,但我仍然希望能够在实现时定义正确的类型,而不是到处使用“动态”。有没有正确的方法来处理这个问题,能够在同一个列表中重新组合所有类型的形状?我希望这很清楚。

我显然简化了整个事情以直截了当,但所涉及的一切都要复杂得多,不能真正放在一个大块中。

安德烈·霍米亚克

如果您的形状属性非常不同,您可以将System.Object其用作常见类型。但是不要忘记检查是否将正确ShapeAttributes的类型传递给正确的实现IShape,所以我建议使用 set 方法而不是属性 setter:

对象定义:


public interface IShape
{
    object ShapeAttributes { get;  }
    Type ShapeAttributesType { get; }
    void SetAttributes(object shapeAttributes);
}

public class Square : IShape
{
    public object ShapeAttributes { get; private set; }
    public Type ShapeAttributesType => typeof(SquareAttributes);     
    public void SetAttributes(object shapeAttributes)
    {
        // Check if passed correct type
        if (shapeAttributes.GetType() != ShapeAttributesType)
            throw new ArgumentException($"Argument type must be {ShapeAttributesType.FullName}", nameof(shapeAttributes));
        ShapeAttributes = shapeAttributes;
    }
}

public class Circle : IShape
{
    public object ShapeAttributes { get; private set; }
    public Type ShapeAttributesType => typeof(CircleAttributes);        
    public void SetAttributes(object shapeAttributes)
    {
        // Check if passed correct type
        if (shapeAttributes.GetType() != ShapeAttributesType)
            throw new ArgumentException($"Argument type must be {ShapeAttributesType.FullName}", nameof(shapeAttributes));
        ShapeAttributes = shapeAttributes;
    }
}

public struct SquareAttributes
{
    public float SizeOfSide { get; set; }
}

public struct CircleAttributes
{
    public float Radius { get; set; }
}

使用示例:


List<IShape> shapes = new List<IShape>();
var square = new Square();
square.SetAttributes(new SquareAttributes()
{
    SizeOfSide = 4.1f
});

var circle = new Circle();
circle.SetAttributes(new CircleAttributes()
{
    Radius = 2.12f
});

shapes.Add(square);
shapes.Add(circle);

foreach (var shape in shapes)
{
    //Cast ShapeAttributes based on owner class type
    switch (shape)
    {
        case Square s:
            var size = ((SquareAttributes)s.ShapeAttributes).SizeOfSide;
            Console.WriteLine($"Square.ShapeAttributes.SizeOfSide = {size}");
            break;
        case Circle c:
            var radius = ((CircleAttributes)c.ShapeAttributes).Radius;
            Console.WriteLine($"Circle.ShapeAttributes.Radius = {radius}");
            break;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章