簡體   English   中英

從抽象類繼承抽象擴展方法

[英]Abstract extension method inheritance from abstract class

我正在嘗試實現以下目標,尚不確定是否有可能:(在幕后是我嘗試做的CarFactory-實現Factory設計模式)

我有一個抽象類“汽車”,該類具有在所有汽車之間共享的實體屬性,並且具有並非所有汽車都具有的諸如“ 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,它增加了汽車的成本,並且說要改善Car的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#中甚至可能嗎? 也許有不同的方向嗎?

您總是可以定義一個接口(或使用您的抽象類):

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

從站點:

“裝飾器模式用於在不更改其結構的情況下向現有對象添加新功能。因此,裝飾器模式提供了一種替代的繼承方式,用於修改對象的行為。”

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

而我們喜歡

myCar.Install(V1);

(假設V1是您的FuelInjection實例)。 此處不需要泛型,因為所有功能都繼承自Feature

但實際上,我看不出這比直接調用V1.Install(car)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM