2017-07-28 3 views
0

開始する前に、これはこれを行う理想的な方法ではないことを認識しておきたいと思います。ただし、呼び出しのクラスは割り当ての規則に従って変更することはできません。私はこの問題を理解し解決することを試みたが、運がなかった。C#スーパークラスが呼び出し元クラスからキャストせずに3つの可能な型を返す方法

下に1つのスーパークラス、TreeMangement(これらのサブクラスには1つのスーパークラスしか存在できません)があります。 3つのサブクラス(リンゴ、オレンジ、バナナ)があります。 "find"メソッドはTreeMangementスーパークラスになければなりません。私は "find"メソッドをオーバーライドすることは許されていません。現在のコードでは、呼び出し側クラスでキャストエラーが発生します。 TreeMangementは、暗黙のうちにAppleTree、OrangeTree、またはBananaTreeにキャストすることはできません。

私の質問は、呼び出し元のクラスにキャストせずに、どのタイプ(Apple、Banana、Orange)が呼び出していても、呼び出し元のクラスに正しい型を渡すことができるかどうかです。もしそうなら、どうですか?もしそうでなければ、私は知っているので、それを行う方法は絶対にありません。

public class TreeMangement 
{ 
    public string id {get; set;} 

    public TreeMangement() 
    { 
     id = this.GetType().Name+"|"+Guid.NewGuid(); 
    } 

    public static TreeMangement Find(string idIn) 
    { 
     string type = idIn.Split('|')[0]; 
     return Functions.GetObj(idIn, GetFilePath(type), type); //returns back the right type 
    } 
} 




public class AppleTree:TreeMangement 
{ 
    public string Name; 
} 

public class OrangeTree:TreeMangement 
{ 
    public string Name; 
} 

public class BananaTree:TreeMangement 
{ 
    public string Name; 
} 


///////Calling class//// 

AppleTree savedAppleTree = AppleTree.Find("SomeValidID"); 
OrangeTree savedOrangeTree = OrangeTree.Find("SomeValidID"); 
BananaTree savedBananaTree = BananaTree.Find("SomeValidID"); 
+0

戻り値の型がジェネリックパラメータであるのに対し、 'Find()'をジェネリックメソッドにするか、サブクラスで 'Find()'を隠してそこにキャストを実装します。 – ViRuSTriNiTy

+0

一般的なメソッドの場合、呼び出し元クラスから型を渡す必要がありますか?あるいは、サブクラスがそれを呼んでいることに基づいて推論しますか? サブクラスでfind()を非表示にすることはできません。 –

+0

私の答えを見てください – ViRuSTriNiTy

答えて

1

あなたはこのような一般的なスーパークラスにスーパークラスを変更することができます。

public class TreeMangement<T> 
    where T: class 
{ 
    ... 

    public static T Find(string idIn) 
    { 
     return ... as T; 
    } 
} 

は今、あなたはこの方法で

public class AppleTree:TreeMangement<AppleTree> 
{ 
    public string Name; 
} 

public class OrangeTree:TreeMangement<OrangeTree> 
{ 
    public string Name; 
} 

public class BananaTree:TreeMangement<BananaTree> 
{ 
    public string Name; 
} 

ようなあなたのサブクラスで戻り値の型をspecifiyすることができますあなたの3 Find()コールが正しいタイプを返すので、電話を見つけることはうまくコンパイルされます:

var savedAppleTree = AppleTree.Find("SomeValidID"); 
var savedOrangeTree = OrangeTree.Find("SomeValidID"); 
var savedBananaTree = BananaTree.Find("SomeValidID"); 
+0

私はあなたが行くのが好きです。しかし、次のエラーが表示されます。 "呼び出し側クラスのコンパイラ必須メンバー 'Microsoft.CSharp.RunTimeBinder.Binder.Convert'が見つかりません。 –

+1

私は実際に新しいプロジェクトを作成し、このコードを実行しました。エラーが私のfind関数から来ていることを意味します!あなたのコードではありません。この方法について教えてくれてありがとう! –

関連する問題