質問: new ClassC(); // (疑問)アップキャストされた変数を、明示的にではなく、何かしらの手法で動的にダウンキャストした上でメソッドに渡したい // 或いは、メソッドに渡った段階で暗黙的にダウンキャストされた状態にしたい // ClassB, ClassC という文字列をこれ以上記述しない方法を模索したい。 // 失敗例 // Hoge((ClassB)instance); // 明示的なので、今回の要件には不適切 // Hoge(instance as ClassB); // 同上 // 条件付き成功例 // Hoge((dynamic)instance); // Unity2017.1.0p4 で .NET4.6 を使えるようにすれば動く Hoge(instance); // error Moge(instance); // error } // 下記の Hoge() と Moge() は変更しない void Hoge(ClassB instance) { instance.Hoge(); } void Moge(ClassC instance) { instance.Moge(); } } public class ClassA : Object { } public class ClassB : ClassA { public void Hoge() { Debug.Log("hogehogehoge"); } } public class ClassC : ClassB { public void Moge() { Debug.Log("mogemogemoge"); } } ``` ### エラー ``` 後述のソースコードをそのまま書くと下記エラーが出る - Assets/TestClassAlgorythmMain.cs(13,9): error CS1502: The best overloaded method match for `TestClassAlgorythmMain.Hoge(ClassB)' has some invalid arguments - Assets/TestClassAlgorythmMain.cs(13,14): error CS1503: Argument `#1' cannot convert `ClassA' expression to type `ClassB' Unity 5.5.0f3 で(dynamic)を使うと、Unity 上で二つのエラーが出る - Assets/TestClassAlgorythmMain.cs(12,15): error CS1980: Dynamic keyword requires `System.Runtime.CompilerServices.DynamicAttribute' to be defined. Are you missing System.Core.dll assembly reference? - Assets/TestClassAlgorythmMain.cs(12,9): error CS1969: Dynamic operation cannot be compiled without `Microsoft.CSharp.dll' assembly reference ``` ### 試したこと リフレクション関連を使えば何か出来るかと思ったが、そもそも C# 初心者レベルなので作法が良く分からなかった。 ### 補足情報(言語/FW/ツール等のバージョンなど) Unity2017.1.0p4, Unity 5.5.0f3 共に C#
回答: `as演算子`を使用してはいかがでしょうか。 as演算子でダウンキャストできない場合はnullに変換されます。 ``` ClassA instance = new ClassB(); Hoge(instance as ClassB); ``` **(追記)** 「Hoge()が実装されているインスタンスならそれを実行する」というのであれば、`interface`を使用します。 ClassA継承にかかわらず、IHasHogeインターフェイスを実装していればキャストされます。 ``` public class TestClassAlgorythmMain : MonoBehaviour { void StartX () { // アップキャスト ClassA instance = new ClassB(); Hoge(instance); } void Hoge(object instance) { var p = instance as IHasHoge; if (p != null) { p.Hoge(); } } } public interface IHasHoge { void Hoge(); } public class ClassA : Object {} public class ClassB : ClassA, IHasHoge { public void Hoge() { Debug.Log("hogehogehoge"); } } ```