2016-11-27 6 views
0

ジェネリックデリゲートを使用して、インスタンス化されたオブジェクトをゲームエンジンで管理する方法を理解しようとしています。インスタンス化されたオブジェクトを管理するための汎用代理人

ここ

は私が何をしようとしている実証するためのいくつかの擬似コードです:

public class ObjectManager 
{ 
    public delegate void ObjectManagerEvent <T> (T instantiatedObject); 
    public ObjectManagerEvent <T> onObjectInstantiated; 


    public void InstantiateObject (Object objToInstantiate) 
    { 
     var obj = SomeInternalInstantiateMethod(); 

     ObjectManagerEvent _onObjectInstantiated = onObjectInstantiated; 
     if (_onObjectInstantiated != null) 
     { 
      _onObjectInstantiated (obj); 
     } 
    } 
} 


public class Shape : EBehaviour {} 
public class Animal : EBehaviour {} 


public class DemoShape 
{ 
    private void Init() 
    { 
     ObjectManager.onObjectInstantiated += OnObjectInstaniated; 
    } 

    public void OnObjectInstaniated (Shape shape) 
    { 
     // do something with shape 
    } 
} 

public class DemoAnimal 
{ 
    private void Init() 
    { 
     ObjectManager.onObjectInstantiated += OnObjectInstaniated; 
    } 

    public void OnObjectInstaniated (Animal animal) 
    { 
     // do something with animal 
    } 
} 

私はpublic ObjectManagerEvent <T> onObjectInstantiated();がエラーをスローすることを知っているが、私はちょうど種類の失われたものを私を達成するためにどのようにです欲しいです。

任意のポインタ?

答えて

2

まず、デリゲートの構文はC#1.0です。

オプション1

C#で使用すると、一般的なイベントを宣言するために、オープンジェネリック型を使用することはできませんので、あなたが特にシンプルかつエレガントな方法でこれを行うことはできません。それぞれがイベントを持つオブジェクトの辞書を作成し、汎用メソッドを使用してこの辞書にアクセスできます。

また、新しいインスタンスを作成して返すようにInstantiateObjectを使用するとします。ここでは、すべてがパラメータなしコンストラクタを持つクラスだとも仮定します。

public static class ObjectManager 
{ 
    public class TypeEvent<T> 
    { 
     // Our event handler will accept a parameter of type T and return void 
     public event Action<T> OnObjectInstantiated; 

     public void RaiseObjectInstantiated(T obj) 
     { 
      OnObjectInstantiated?.Invoke(obj); 
     } 
    } 

    private static Dictionary<Type, object> _typeMap = new Dictionary<Type, object>(); 

    public static TypeEvent<T> ForType<T>() where T: class, new() 
    { 

     Type t = typeof(T); 
     if (!_typeMap.ContainsKey(t)) 
     { 
      _typeMap[t] = new TypeEvent<T>(); 
     } 
     return _typeMap[t] as TypeEvent<T>; 

    } 

    public static T InstantiateObject<T>() where T: class, new() 
    { 
     T obj = new T(); 
     ForType<T>().RaiseObjectInstantiated(obj); 
     return obj; 
    } 
} 

あなたがそうのようにそれを使用することができます:あなたはObjectManagerの自身の静的ジェネリッククラスを作成すると大丈夫です場合

 ObjectManager.ForType<Foo>().OnObjectInstantiated += fooInstantiated; 
     Foo f = ObjectManager.InstantiateObject<Foo>(); 

オプション2

、あなたは非常にこれを簡素化することができます。これは、ObjectManagerクラスが1つしかないことに注意してください。ObjectManager<Foo>ObjectManager<Bar>は、変数が異なる別のクラスになりました。これが受け入れられる場合、これにより、ObjectManagerが行う必要があることをあなたに教えてくれた小さなことのために、よりクリーンなものになります。

public static class ObjectManager<T> where T : class, new() 
{ 
    // Our event handler will accept a parameter of type T and return void 
    public static event Action<T> OnObjectInstantiated; 

    public static T InstantiateObject() 
    { 
     T obj = new T(); 
     OnObjectInstantiated?.Invoke(obj); 
     return obj; 
    } 
} 
関連する問題