2017-10-01 5 views
0

私は、基本クラスがあり、カップルが派生インタフェースを実装するクラス、例えば場合:C#:実行時に実装するインターフェイスにクラスをキャストする方法はありますか?

public class BaseClass 
{ 

} 

public interface IInterface 
{ 
    void SomeMethod(); 
} 

public class DerivedA : BaseClass, IInterface 
{ 
    public void SomeMethod() 
    { 
     // some implementation 
    } 
} 
public class DerivedB: BaseClass, IInterface 
{ 
    public void SomeMethod() 
    { 
     // some other implementation 
    } 
} 

をそして、私はBaseClassのフィールドを持つ無関係なクラスがあります。私の実装が前提として提供

public class UnrelatedClass 
{ 
    public BaseClass foo; 
} 

をfooはインターフェイスを実装するいくつかの派生クラスでなければなりません(しかし、私はそのクラスにキャストできないのか分かりません)、それをIInterfaceにキャストしてfoo.SomeMethod()を呼び出すとコンパイルエラーは発生しません。 ?

PS-これを行うには本当にラウンドアバウトの方法ですが、代わりに "IInterface foo"フィールドを使用する必要がありますが、Unityがインターフェイスフィールドをシリアル化せず、カスタムインスペクタを作成したくないため - これは回避策です私はしようとしています。

+0

'BaseClass'は' SomeMethod'を持っているdoesntの。 'IInterface'はそれを持っています。なぜ、' SomeClass'の中に 'SomeMethod'を入れないのですか? '抽象'? – FCin

+0

なぜ 'BaseClass'は' IInterface'を実装していませんか? –

+1

'is'キーワードを使って' if(foo is IInterface){...} 'を確認してください。 – CodingYoshi

答えて

4

あなたは反射(遅い!)によってインターフェイスメソッドにアクセスできます。またはasオペレータで '安全-キャスト'することができます。 as演算子は、キャストに失敗した場合はnullを返します。このように:

var impl = foo as IInterface; 
impl?.SomeMethod() 
// or if(impl != null) impl.SomeMethod(); 
+0

ニース!しばらくこの質問を忘れましたが、これは私が探していたものでした。私はコンパイル時にコンバーチブルではない型として "as"を使うことができるかどうかは分かりませんでした。ありがとう:) – user2944295

0

私はあなたのデザインを変更して解決策を提供します。あなたの究極の目標は、あなたのfooオブジェクトがBaseClassIInterfaceのすべてのメンバーを持つようにすることです。あなたはそうのような抽象クラスを作成することができます。

abstract class BaseClassAndInterface: BaseClass, IInterface { 
    public abstract void SomeMethod(); 
} 

は今BaseClassAndInterfaceからDerivedADerivedB継承を行い、インタフェースのメソッドを実装します。今

public class DerivedA : BaseClassAndInterface 
{ 
    public override void SomeMethod() 
    { 
     // some implementation 
    } 
} 
public class DerivedB: BaseClassAndInterface 
{ 
    public override void SomeMethod() 
    { 
     // some other implementation 
    } 
} 

fooBaseClassAndInterfaceとして宣言することができます。

+0

私はこれを考えました - それは私が与えたが、あなたがIInterfaceを実装する異なる基底クラスを使用したい場合には、 )。 実際に私の元の問題(オブジェクト間の衝突を渡す)には別の回避策がありましたが、これは仮想的な観点からはまだ分かりません。実行時に__does__を実装するオブジェクトからインタフェースメンバを使用できますか?コンパイル時に変数__doesn't__? – user2944295

1

現在、BaseClassにはデザイン上の要点はありません。設計を少し変更した場合は、実行時にチェックを実行する必要がない場合もあります。ここでBaseClassIInterfaceを実装し、派生クラスはそれをオーバーライドする必要が前記提案された設計されています

public interface IInterface 
{ 
    void SomeMethod(); 
} 

public abstract class BaseClass : IInterface 
{ 
    public abstract void SomeMethod(); 
    // Or virtual with common implementation 
} 

public class DerivedA : BaseClass 
{ 
    public override void SomeMethod() 
    { 
     // some implementation 
    } 
} 
public class DerivedB : BaseClass 
{ 
    public override void SomeMethod() 
    { 
     // some other implementation 
    } 
} 
関連する問題