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

Abstract extension method inheritance from abstract class

我正在努力实现以下目标,但不确定是否可行: (幕后是我尝试做的CarFactory——实现工厂设计模式)

我有一个抽象的 class "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) ; 

理想情况下它应该这样做,但我有编译器错误-

Extension method must be defined in a non-generic static class

当然我不想要一个通用的静态方法,我想要一个具有相同签名但会在每个 class 继承 Feature 的汽车上做一些不同的事情的方法。

功能的示例是 FuelInjection,它增加了汽车的成本,假设改善汽车的 FuelConsumption 属性。

抽象特征class:

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# 中这甚至可能吗? 也许有不同的方向可以走?

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

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

如果您的摘要 class 只是:

public static class CarExt
{
     public static void InstallFeature(this Car car, Feature feature) 
     {
         feature.Install(car);  
     }
}

编译器消息已经告诉您,按照您尝试的方式是不可能的。扩展方法 必须 static static class.[=18 的 static 方法=]

所以你只能将你的方法声明为简单的abstract/instance方法:

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

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

但实际上,我看不出这比直接调用 V1.Install(car) 有什么好处。

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

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

来自网站:

"Decorator pattern is used to add new functionality to an existing object without changing its structure. Hence Decorator pattern provides an alternative way to inheritance for modifying the behavior of an object."

来自 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();

 }
}