2012-03-20 7 views
1
私は

はジェネリックの型の安全性を取得したときにジェネリックを使用しない

public class MyVehicleCollection<T> where T : Vehicle 
{ 
    private List<T> listofVehicles = new List<T>(); 

    public void AddVehicle(T v) { listofVehicles.Add(v); } 
} 

public class MyVehicleCollection<Vehicle> 
{ 
    private List<Vehicle> listofVehicles = new List<Vehicle>(); 

    public void AddVehicle(Vehicle v) { listofVehicles.Add(v); } 
} 

の違いについては不明だ

私は表示されない理由は、両方のケースで、唯一の可能性Vehicleから派生した型をコレクションに追加します。なぜ私はMotobikeを格納するための追加のコレクションクラスを作成する必要があるのか​​わかりません。

事前に感謝します。あなたの第二の形式が全く車両にバインドされていない

+0

将来的に必要または期待されない拡張性をトレードします。確かにあなたは将来的に自転車を追加することができますが、あなたはそれをやろうとしていますか?未来に応じて、クローズドまたはオープンなアーキテクチャを作成できます。 – CodingBarfield

+1

ジェネリック型パラメータとクラス名の両方で 'Vehicle'を使用しているという混乱が原因です。 –

答えて

1

:あなたの説明から

public class MyVehicleCollection<Vehicle> 
{ 
} 

... 

var coll = new MyVehicleCollection<string>(); 

、あなたはすべてのジェネリックを必要としていないようです。

public class MyPlainVehicleCollection //<Vehicle> no Type Parameter 
{ 
    private List<Vehicle> listofVehicles = 
      new List<Vehicle>(); // class Vehicle 

    public void AddVehicle(Vehicle v) { listofVehicles.Add(v); } 
} 

私はMotobike : Vehicle

を含む ための追加のコレクションクラスを作成する必要があるだろう、なぜまたあなたがいない表示されていない。

var garage = new MyPlainVehicleCollection(); 
garage.Add(new Motobike()); 
+0

したがって、はクラス定義行で何をしますか?つまり、コンパイラには何が伝えられていますか?それを放置することはできますか? – gwizardry

+0

」はタイプパラメータです。クラスと同じ名前を使用することは危険です。 2番目のサンプルを ''と書いて、何が起こったかを見てください。 –

+0

「それは放置できますか?」 - それは決して同じではありません。時にはそれが残されていることがあります。 –

0

の違い2つは実行時ではなくコンパイル時です。

最初のケースでは、VehicleまたはVehicleから派生した型でのみMyVehicleCollectionを宣言できます。

2番目のケースでは、@Henk Holtermanが既に言ったように、任意のタイプのMyVehicleCollectionを宣言できます。

1

一般的には、Vehicleから派生している限り、クラスで受け入れられた型を強制するために使用します。

あなたは

class Truck : Vehicle {} 

class Van : Vehicle {} 

を持っている場合は、その後、次のコンパイラエラーになり

var x = new MyVehicleCollection<Truck>(); 

を宣言することができます。

x.AddVehicle (new Van()); 
0

は、私はあなたが

//somewhere in the code have a method 
public static string GetVehicleName<T>(T vehicle) where T : Vehicle, new() 
{ 
    return vehicle.GetVehicleName(); 
} 

//abstract class Vehicle 
public abstract class Vehicle 
{ 
    public abstract string GetVehicleName(); 
} 

//Child class 
public class Car : Vehicle 
{ 
    public override string GetVehicleName() 
    { 
    return "Car"; 
    } 
} 

と(それが明確になり、このようにであってもよい)だけでなく、クラス宣言でなく、方法を検討すべきだと思う

GetVehicleName(new Car()); //will return "Car" 

このような使用も、後プロダクションレディーコードではなく、単にあなた、希望、アイデアを与える例です。

それはbasciallyこのことができますVehicles

希望のあらゆるタイプをホストできる機能のために作成し、抽象化レイヤ。

0

この例では、必ずしも利益が示されていません。あなたはそれがあなたのアルゴリズムの制約を満たしていることを確認、可算の任意のタイプでこれを使用することができます

public SuperFastForwardOnlyList<T> : where T : IEnumerable 
{ 
    public void AddList(T childList); 

    //Crazy new algorithm here that is going to earn you a fortune, but must use collections  
    //of the same type. 
} 

たとえば、あなたが子供のリストを含むデータ構造のスーパー新しいタイプを作成し、言います
SuperFastOnlyList<IList> listOfLists = new SuperFastOnlyList<IList>(); 

listOfLists.Add(new List()); //Fine 
listOfLists.Add(new object()); //Whoops - compile time error. 

この例も少し工夫されていますが、より明るいかもしれませんか?

関連する問題