C# C语言中的Fluent接口与多重继承#
这个问题类似于。区别在于我想要两个基类 示例:C# C语言中的Fluent接口与多重继承#,c#,inheritance,multiple-inheritance,fluent-interface,C#,Inheritance,Multiple Inheritance,Fluent Interface,这个问题类似于。区别在于我想要两个基类 示例: 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 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
}
也许圆圈和盒子不是最好的例子。基本上,它们表示具有不同属性和方法的类。类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");
如果:
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
类。就像从单个类进行常规继承一样,CircleAndBox
应该自动从Circle
和Box
使用接口继承所有公共方法:
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
}
使用接口:
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
}
Have
CircleAndBox
继承两个类,而是引用这些类的对象。它必须重新定义每个类中的方法。您可以将隐式转换添加到圆
和框
,以便在需要引用这些对象的上下文中使用它
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
传递给使用框的方法,并期望另一侧的结果是CircleAndBox
CircleAndBox cb = new CircleAndBox();
// Implicit conversion, b contains a Box object.
Box b = cb;
// Compile-time error CS0030.
cb = (CircleAndBox)b;
HaveCircleAndBox
继承两个类,而是引用这些类的对象。它必须重新定义每个类中的方法。您可以将隐式转换添加到圆
和框
,以便在需要引用这些对象的上下文中使用它
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
传递给使用框的方法,并期望另一侧的结果是CircleAndBox
CircleAndBox cb = new CircleAndBox();
// Implicit conversion, b contains a Box object.
Box b = cb;
// Compile-time error CS0030.
cb = (CircleAndBox)b;
我认为你不能完全按照你的期望去做,因为C#(和.Net一般)不支持类的多重继承。您可以从一个类继承并实现一个接口
例如:
interface iBox
{
iBox Width(string width); //Assuming you want Box here and not Circle
}
然后你有一个盒子
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对象。我不确定这是否能达到目的
另外,如果您不控制至少一个要继承的类,那么这将不起作用。我认为您不能完全按照您的期望来做,因为C#(通常是.Net)不支持类的多重继承。您可以从一个类继承并实现一个接口
例如:
interface iBox
{
iBox Width(string width); //Assuming you want Box here and not Circle
}
然后你有一个盒子
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对象。我不确定这是否能达到目的
此外,如果您不控制至少一个要继承的类,这将不起作用。继承意味着“是一个”
球
是一种圆形物体
<代码>圆形
是一种圆形
<代码>框
是一个平方
<代码>兰博基尼是一辆汽车
,汽车
是一辆交通工具
<代码>公共汽车和自行车也是交通工具
如果它不是一个“是”关系,那么它就不是继承。这就是为什么C++和java中不支持多重继承的解释,而我在C++中所了解的大多数人都不赞成。一个物体几乎不可能同时是两件东西
不要仅仅为了保存代码行而滥用继承。即使保存代码行是一个合理的目标(我不同意这一点),它甚至没有必要。在这方面,还有两个构造可以帮助您
首先,关于关系。你要找的是一个完全不同的关系。不是“是a”,而是“可以用作”。这就是接口的用武之地。接口指定对象可以用作什么。因此,您可以有两个接口IBox
和ICircle
。然后,您的CircleAndBox
东西可以实现这两个接口,从而指定它可以同时用作这两个接口
第二,你可以多使用一种关系,让生活更轻松。您将不会保存代码行。但是,您将确保您的CircleAndBox
始终具有在Circle
和Box
类中定义的正确行为。为此,可以使用聚合和委派模式。聚合是一种表示“有一个”的关系。因此,让您的CircleAndBox
类拥有一个私有的Circle
对象和一个私有的Box
对象,然后只需在各自的私有对象上调用相应的方法/属性/事件,并返回它们返回的内容,即可实现ICircle
和IBox
接口
实际上,您有一个类,它有一个(聚合)圆和盒子实例来实际传递工作,它通过使用相同的方法(委托)来公开这些实例,因此可以用作(接口)圆和盒子。继承意味着“是一个”
B