2016-08-31 6 views
0

私はそれがすべて可能であることを確認し、まだ、以下を達成することはないしようとしている: (シーンの後ろに私が実行しようとしましたCarFactoryある - ファクトリデザインパターンを実装する)抽象拡張メソッドの継承

私はすべての車で共有されているソリッドなプロパティを持つ抽象クラス "車"を持っていますし、 "ラジオディスク"、 "FuelInjection"のような機能を持っています。

"RadioDisc"または "FuelInjection"にはいくつかの種類があります。

これらの機能のそれぞれは、特定のパターンに従い、プロパティを共有していますが、車のインストールプロセスは異なります。

私はいくつかのことができる方法に基づいて車に変更を加えたいと思います。

拡張子は次のようになります。

Car myCar = new Car(); //Car is a class which has solid props & List of Feature class 
FuelInjection V1 = new FuelInjection(); 
myCar.Install<FuelInjection>(V1) ; 

理想的には、次のように行う必要がありますが、私は

拡張メソッドは、非ジェネリック静的クラスで定義しなければなりませんエラー - コンパイラを持っています

もちろん、私は一般的な静的メソッドを望んでいませんが、私は同じシグネチャを持つが、フィーチャを継承する各クラスに車を乗せている。

フィーチャの例は、車にコストを追加する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#であっても可能ですか? 多分行く別の方向はありますか?

+3

'MyCar'は何ですか? 'V1'とは何ですか?疑似コードから実際に何を達成しようとしているのかは分かりにくいですが、あなたが本当に拡張メソッドを理解していないという疑いがあります。実際に何をしようとしているのかを説明しようとすると、助けが簡単になります。 –

+3

私はそれが拡張メソッドであるとは思わない。それを通常の抽象メソッドにして、それをあなたの子クラスに実装してください。私はまたあなたがそれがジェネリックであることを必要とするのか疑問に思う。 – juharr

+0

あなたが何を求めているかははっきりしていません。 'Install()'メソッドをインタフェース宣言に入れるだけでは不十分である理由を説明してください。 –

答えて

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

解決策は思ったより簡単です、ありがとうございます。 –

1

コンパイラのメッセージは、あなたがそれを実行しようとしている方法では不可能であることを既に伝えています。拡張方法の静的のメソッドの静的クラスでなければなりません。あなたが望んでいたように呼び出しをラップ

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

よう

そして、私たちは(をと仮定しますはFuelInjectionのインスタンスです)。 ここに汎用性は不要すべての機能はFeatureから継承されています。

実際には、V1.Install(car)を直接呼び出すよりも、これがどのように優れているかわかりません。

2

私があなたの問題を正しく理解していれば、デコレータパターンを探しているはずです。

文献:サイトから http://www.dotnet-tricks.com/Tutorial/designpatterns/VRQT130713-Decorator-Design-Pattern---C

「はDecoratorパターンは、その構造を変えることなく、既存のオブジェクトに新しい機能を追加するために使用されよってDecoratorパターンを修正するための継承する別の方法を提供します。オブジェクトの振る舞いDOTNET-トリックサイトから

コードサンプル:

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

} 
} 
関連する問題