2017-04-25 16 views
-3

実行時キャストエラーが発生しました。次のようなコードで実行時キャストエラーが発生します。まず、私はVisitorパターンとのインタフェースを設定している:C#制約付きジェネリック型から制約型へのランタイムキャストエラー

その後
public interface IAnimalVisitor<out T> 
{ 
    T Visit(Dog a); 
    T Visit(Cat a); 
} 

public interface IAnimal 
{ 
    string Name { get; } 

    T Accept<T>(IAnimalVisitor<T> v); 
} 

public abstract class AnimalBase : IAnimal 
{ 
    public string Name { get; } 

    protected AnimalBase(string name) 
    { 
     Name = name; 
    } 

    public abstract T Accept<T>(IAnimalVisitor<T> v); 
} 

public class Dog : AnimalBase 
{ 
    public Dog(string name) : base(name) { } 

    public override T Accept<T>(IAnimalVisitor<T> v) 
    { 
     return v.Visit(this); 
    } 
} 

public class Cat : AnimalBase 
{ 
    public Cat(string name) : base(name) { } 

    public override T Accept<T>(IAnimalVisitor<T> v) 
    { 
     return v.Visit(this); 
    } 
} 

(入れ子になったクラスとして隠れて)ビジターパターンの実装クラス:

public class AnimalSpeaker 
{ 
    private class SpeakerVisitor : IAnimalVisitor<string> 
    { 
     public string Visit(Dog a) 
     { 
      return "Woof"; 
     } 

     public string Visit(Cat a) 
     { 
      return "Meow"; 
     } 
    } 

    private readonly SpeakerVisitor _SpeakerVisitor = new SpeakerVisitor(); 

    public string Speak(IAnimal a) 
    { 
     return a.Accept(_SpeakerVisitor); 
    } 
} 

そして最後に、私はジェネリッククラスはに拘束されているがそのカプセル化クラスを介して訪問者にインスタンスを渡しIAnimalsの種類を消費:

public abstract class AnimalSignTextBuilderBase<TAnimal> 
    where TAnimal : IAnimal 
{ 
    private readonly AnimalSpeaker _AnimalSpeaker = new AnimalSpeaker(); 

    public string BuildSignText(TAnimal a) 
    { 
     var spokenText = _AnimalSpeaker.Speak(a); 
     return $"{a.Name} says {spokenText}."; 
    } 
} 

public class DogSignTextBuilder : AnimalSignTextBuilderBase<Dog> { } 
public class CatSignTextBuilder : AnimalSignTextBuilderBase<Cat> { } 

このコードは完全に罰金コンパイルが、実行時に(それがから呼ばれていますn ASP.netリクエスト)

new DogSignTextBuilder().BuildSignText(new Dog("Fido")) 

無効なキャスト例外が発生します。これは_AnimalSpeaker.Speak(a)を呼び出すことによって発生します。

なぜこれがスローされるのかわかりません。さらに、私はVisual Studioでコードをデバッグし、trueの結果として、即時ウィンドウにa is IAnimalと入力することができます。私はまた、イミディエイトウィンドウで_AnimalSpeaker.Speak(a)を入力することができ、それは、次のエラーが発生:この時点で私がでてるので、

error CS1503: Argument 1: cannot convert from 'TAnimal' to 'IAnimal' 

私もこの例に取ると、dotnetfiddleにそれを投稿し、それが正常に動作することができ何が起こっているのかについてのアイデアのための総損失。

編集:私は私の参照をチェックして、彼らはすべてそこにいる

error CS1061: 'TAnimal' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'TAnimal' could be found (are you missing a using directive or an assembly reference?) 

私もちょうどイミディエイトウィンドウでa.Nameを呼び出すことに起因して失敗したことがわかりました。これまでのところ、一般的な制約は実行時に無視されているようです。私も(a as IAnimal).Nameと入力することができ、これは正しくFidoを返します。

+2

最小限の例を減らすことはできますか?私は、問題を示すために、すべてのコードが必要になるとは思っていませんでした。 –

+1

あなたの主張が*例外*であるという主張は、コンパイラエラーである "エラーCS1503"とうまく適合しませんが... –

+0

コードの残りの部分が赤いニシン。私はこれが私にとって意味をなさないと私が与えることができるように完全にしたいと思った。 –

答えて

0

これは、私がそれが関係していると思ったすべてに完全に無関係の問題であった。要するに、デリゲートがジェネリック入力ではなく、適切に値をキャストできなかったことです。

関連する問題