抽象扩展方法继承自抽象类

本文关键字:抽象类 继承 方法 扩展 抽象 | 更新日期: 2023-09-27 18:04:53

我正在努力实现以下目标,但不确定它是否完全可能:(在场景的后面是我尝试做的一个CarFactory——实现工厂设计模式)

我有一个抽象类"Car",它具有所有汽车之间共享的实体属性,并且我有像"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的类的car做一些不同的事情。

功能的例子是燃料注入,增加成本到汽车,让我们说,改善燃料消耗属性的汽车。

抽象特征类:

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#中可能吗?有没有别的方向可以走?

抽象扩展方法继承自抽象类

你总是可以定义一个接口(或者使用你的抽象类):

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);  
     }
}

如果我正确理解了你的问题,你应该寻找装饰模式。

参考:http://www.dotnet-tricks.com/Tutorial/designpatterns/VRQT130713-Decorator-Design-Pattern--C

从站点:

"Decorator模式用于在不改变现有对象结构的情况下为其添加新功能。因此,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();
 }
}

编译器消息已经告诉您,按照您尝试的方式这是不可能的。扩展方法必须是静态类的静态方法。

所以你只能将你的方法声明为简单的抽象/实例方法:

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);
    }
}

And us it like

myCar.Install(V1);

(假设V1FuelInjection的实例)。这里的不需要泛型,因为所有的特性都继承自Feature

但实际上,我不认为这比直接调用V1.Install(car)好。