此问题类似于 this one 。不同之处在于我希望有两个基类。
示例:
public class Circle
{
private string _radius { get; set; }
public Circle Radius(string radius)
{
_radius = radius;
return this;
}
}
public class Box
{
private string _width { get; set; }
public Circle Width(string width)
{
_width = width;
return this;
}
}
public class CircleAndBox : Circle, Box // Can't do in c#
{
// should contain methods from both Circle and Box, but return CircleAndBox
}
也许Circle和Box不是最好的例子。基本上它们代表具有不同属性和方法的类。 CircleAndBox类恰好具有与Circle和Box相同的属性和方法。 CircleAndBox可能具有其他属性和方法,这些属性和方法既不存在于Circle也不存在于Box中。
期望的结果
我应该写:
var circle = new Circle().Radius("5");
var box = new Box().Width("6");
var circleAndBox = new CircleAndBox().Radius("5").Width("6");
如果:
,那将是超级当我向Circle
或Box
课程添加方法时,我不应该触及CircleAndBox
课程。就像从单个类中定期继承一样,CircleAndBox
应该自动继承Circle
和Box
答案 0 :(得分:4)
让CircleAndBox
继承自这两个类,而不是那些类的引用对象。它必须重新定义每个类的方法。您可以将隐式转换添加到Circle
和Box
,以允许它在需要引用这些对象的上下文中使用。
public class CircleAndBox
{
public Circle Circle { get; private set; }
public Box Box { get; private set; }
public CircleAndBox()
{
Circle = new Circle();
Box = new Box();
}
public CircleAndBox Radius(string radius)
{
Circle.Radius(radius);
return this;
}
public CircleAndBox Width(string width)
{
Box.Width(width);
return this;
}
public static implicit operator Circle(CircleAndBox self)
{
return self == null ? null : self.Circle;
}
public static implicit operator Box(CircleAndBox self)
{
return self == null ? null : self.Box;
}
}
请注意,隐式转换不会保留对象的类型,因此不应使用此技术将CircleAndBox
传递给采用Box
的方法,并期望在另一侧获得结果成为CircleAndBox
。
CircleAndBox cb = new CircleAndBox();
// Implicit conversion, b contains a Box object.
Box b = cb;
// Compile-time error CS0030.
cb = (CircleAndBox)b;
答案 1 :(得分:2)
继承意味着“是一个”。
Ball
是RoundThing
。 Circle
是RoundThing
。 Box
是SquareThing
。 Lamborghini
是Car
,Car
是Transport
。 Bus
和Bicycle
也是Transport
s。
如果它不是“是”关系,则不是继承。这就解释了为什么C#和Java不支持多继承,而且我在C ++中认识的大多数人都不鼓励这种继承。一个对象几乎不会同时出现两件事。
不要仅仅为了保存代码行而滥用继承。即使保存代码行是一个合法的目标(我不同意),它甚至是不必要的。另外两个结构可以帮助你。
首先,关于这种关系。你在寻找的是一种完全不同的关系。不是“是”,而是“可以用作”。这就是接口的用武之地。接口指定了对象的用途。所以你可以有两个接口IBox
和ICircle
。然后,您的CircleAndBox
事件可以实现两个接口,从而指定它可以同时用作两者。
其次,您可以再使用一种关系来简化生活。您不会保存代码行。但是,您将确保CircleAndBox
始终具有Circle
和Box
类中定义的正确行为。为此,您可以使用聚合以及委派模式。聚合是一种说“有一个”的关系。因此,让您的CircleAndBox
类具有私有Circle
对象和私有Box
对象,然后通过调用相应的方法/实现ICircle
和IBox
接口相应私有对象上的属性/事件,并返回它们返回的内容。
Presto,你有一个类有一个(聚合)Circle和Box实例来实际传递工作,通过使用相同的方法(委托)公开它们,因此可以用作(界面)圆圈和作为方框。
答案 2 :(得分:1)
使用接口:
IBox和ICircle
public interface IBox
{
Circle Width(string width)
}
public interface ICircle
{
Circle Radius(string radius)
}
public class Circle : ICircle
{
private int _radius { get; set; }
public Circle Radius(string radius)
{
_radius = radius;
return this;
}
}
public class Box : IBox
{
private int _width { get; set; }
public Circle Width(string width)
{
_width = width;
return this;
}
}
public class CircleAndBox : ICircle, IBox
{
// should contain methods from both Circle and Box, but return CircleAndBox
}
答案 3 :(得分:0)
我认为你不能完全按照你期望的那样做,因为C#(和.Net一般)不支持多继承类。您可以从一个类继承并实现一个接口。
例如:
interface iBox
{
iBox Width(string width); //Assuming you want Box here and not Circle
}
然后你有Box
class Box : iBox ...
现在你可以拥有
public class CircleAndBox : Circle, iBox
{
private Box _helper;
public iBox Width(string width) { _helper.Width(width); return this; }
}
这不完全是你想要的,但它与我认为的C#一样接近。如果您愿意使用弱类型,还有一种委托方法,用于将事物传递给_helper而不显式实现每个方法。但是,使用直接委派时,您不会返回CircleAndBox对象,而是返回_helper对象。我不确定这是否有用。
此外,如果您不控制至少一个要继承的类,这将无效。