我试图实现以下目标,但还不确定它是否可能: (幕后是我试图做的CarFactory--实现工厂设计模式)
我有一个抽象的课程" Car"具有在所有汽车之间共享的坚固属性,我有像#34; RadioDisc"," FuelInjection"并非所有汽车都有。
可能有几种类型的" RadioDisc"或" FuelInjection"。
这些功能都遵循某种模式,具有共享属性,但汽车上的安装过程不同。
我希望每个功能都能根据可以执行某些操作的方法对Car进行更改。
扩展名应如下所示:
Car myCar = new Car(); //Car is a class which has solid props & List of Feature class
FuelInjection V1 = new FuelInjection();
myCar.Install<FuelInjection>(V1) ;
理想情况下应该这样做,但我有编译错误 -
扩展方法必须在非泛型静态类中定义
当然,我不想要一个通用的静态方法,我想要一个具有相同签名的方法,但是会在每个继承Feature的类上对汽车做一些不同的事情。
功能的示例是FuelInjection,它将成本添加到汽车中,让我们说改善汽车上的FuelConsumption属性。
摘要要素类:
public abstract class Feature
{
internal float _cost;
public float Cost
{
get
{
return _cost;
}
}
public abstract void Install<T>(this Car car) where T : Feature;
}
具体功能:
public class FuelInjection : Feature
{
public new void Install<T>(this Car car) where T : Feature
{
//In iDo some stuff to Car:
car.price += this._cost; //this suppose to be the Feature instance.
//I want to add the cost to property "Price" in Car.
}
}
在c#中甚至可以吗? 是否还有不同的方向?
答案 0 :(得分:2)
您始终可以定义界面(或使用您的抽象类):
public interface IFeature
{
void Install(Car car);
}
从中继承:
public class Feature : IFeature, IComparable
{
public void Install(Car car)
{
....
}
}
然后进行扩展:
public static class CarExt
{
public static void InstallFeature(this Car car, IFeature feature)
{
feature.Install(car);
}
}
如果你的抽象类只是:
public static class CarExt
{
public static void InstallFeature(this Car car, Feature feature)
{
feature.Install(car);
}
}
答案 1 :(得分:2)
如果我理解你的问题,你应该寻找装饰模式。
价: http://www.dotnet-tricks.com/Tutorial/designpatterns/VRQT130713-Decorator-Design-Pattern---C
来自网站:
“装饰器模式用于向现有对象添加新功能而不改变其结构。因此,Decorator模式提供了一种替代方法来继承以修改对象的行为。”
来自dotnet-tricks网站的代码示例:
/// <summary>
/// The 'Component' interface
/// </summary>
public interface Vehicle
{
string Make { get; }
string Model { get; }
double Price { get; }
}
/// <summary>
/// The 'ConcreteComponent' class
/// </summary>
public class HondaCity : Vehicle
{
public string Make
{
get { return "HondaCity"; }
}
public string Model
{
get { return "CNG"; }
}
public double Price
{
get { return 1000000; }
}
}
/// <summary>
/// The 'Decorator' abstract class
/// </summary>
public abstract class VehicleDecorator : Vehicle
{
private Vehicle _vehicle;
public VehicleDecorator(Vehicle vehicle)
{
_vehicle = vehicle;
}
public string Make
{
get { return _vehicle.Make; }
}
public string Model
{
get { return _vehicle.Model; }
}
public double Price
{
get { return _vehicle.Price; }
}
}
/// <summary>
/// The 'ConcreteDecorator' class
/// </summary>
public class SpecialOffer : VehicleDecorator
{
public SpecialOffer(Vehicle vehicle) : base(vehicle) { }
public int DiscountPercentage { get; set; }
public string Offer { get; set; }
public double Price
{
get
{
double price = base.Price;
int percentage = 100 - DiscountPercentage;
return Math.Round((price * percentage) / 100, 2);
}
}
}
/// <summary>
/// Decorator Pattern Demo
/// </summary>
class Program
{
static void Main(string[] args)
{
// Basic vehicle
HondaCity car = new HondaCity();
Console.WriteLine("Honda City base price are : {0}", car.Price);
// Special offer
SpecialOffer offer = new SpecialOffer(car);
offer.DiscountPercentage = 25;
offer.Offer = "25 % discount";
Console.WriteLine("{1} @ Diwali Special Offer and price are : {0} ", offer.Price, offer.Offer);
Console.ReadKey();
}
}
答案 2 :(得分:1)
编译器消息已告诉您,您尝试这样做的方式是不可能的。扩展方法必须是 static 类的静态方法。
因此,您只能将方法声明为简单的抽象/实例方法:
public abstract class Feature : IComparable
{
internal float _cost;
public abstract void Install(Car car);
}
public class FuelInjection : Feature
{
public override void Install(Car car)
{
car.price += this._cost;
}
}
但是您可以使用Feature
参数创建一个简单的扩展,以便按照您的意愿包装调用:
public static class CarExtensions
{
public static void Install(this Car car, Feature feature)
{
feature.Install(car);
}
}
我们喜欢
myCar.Install(V1);
(假设V1
是您FuelInjection
的实例)。由于所有功能都继承自Feature
,因此无需使用泛型。
但实际上,我不知道这比直接拨打V1.Install(car)
更好。