[英]Fluent interfaces and multiple inheritance in C#
這個問題與此類似。 區別在於我想擁有兩個基類。
例:
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 and 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
繼承所有公共方法。
讓CircleAndBox
從這兩個類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;
繼承的意思是“是”。
Ball
是RoundThing
。 Circle
是Circle
的RoundThing
。 Box
是一個SquareThing
。 Lamborghini
是Car
, Car
是Transport
。 Bus
和Bicycle
也是Transport
。
如果不是“是”關系,則它不是繼承。 這就是為什么在C#和Java中不支持多重繼承的原因,而我在C ++中認識的大多數人都不建議使用多重繼承。 一個對象幾乎永遠不會是兩件事。
不要僅僅為了保存代碼行而濫用繼承。 即使保存代碼行是一個合法的目標(我不同意),也沒有必要。 另外兩個構造可以在這里為您提供幫助。
首先,關於關系。 您正在尋找的是完全不同的關系。 不是“是”,而是“可以用作”。 這就是接口進入的地方。接口指定對象可以用作什么。 因此,您可以有兩個接口IBox
和ICircle
。 然后,您的CircleAndBox
事物可以實現這兩個接口,因此指定可以同時使用這兩個接口。
其次,您可以使用一種以上的關系來簡化生活。 您將不會保存代碼行。 但是,您將確保CircleAndBox
始終具有正確的行為,這些行為在Circle
和Box
類中定義。 為此,您可以將聚合與委托模式一起使用。 聚合是一個表示“具有”的關系。 因此,使您的CircleAndBox
類具有一個專用的Circle
對象和一個專用的Box
對象,然后只需在各個專用對象上調用相應的方法/屬性/事件,即可實現ICircle
和IBox
接口,並返回它們返回的值。
Presto,您有一個具有 (聚合)Circle和Box實例的類, 可以將工作實際傳遞給該實例,該實例通過具有相同的方法(委托)公開這些實例,因此可以用作 Circle的(接口) 和框。
使用界面:
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
}
我不認為您可以完全如您所願,因為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對象。 我不確定這將達到目的。
另外,如果您不控制要繼承的類中的至少一個,則此方法將無效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.