Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#管理实例化对象的通用委托_C#_Generics_Architecture_Game Engine - Fatal编程技术网

c#管理实例化对象的通用委托

c#管理实例化对象的通用委托,c#,generics,architecture,game-engine,C#,Generics,Architecture,Game Engine,我试图弄清楚如何使用通用委托来管理游戏引擎中的实例化对象 下面是一些伪代码来演示我要做的事情: public class ObjectManager { public delegate void ObjectManagerEvent <T> (T instantiatedObject); public ObjectManagerEvent <T> onObjectInstantiated; public void InstantiateObje

我试图弄清楚如何使用通用委托来管理游戏引擎中的实例化对象

下面是一些伪代码来演示我要做的事情:

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 
    }
}
公共类对象管理器
{
公共委托void objectmanagervent(T实例化对象);
公共目标管理针对所设定的目标;
公共无效实例化对象(对象对象对象实例化)
{
var obj=someInternalInstanceMethod();
ObjectManagerEvent _onObjectInstated=onObjectInstated;
如果(_onObjectInstated!=null)
{
_onObjectInstantiated(obj);
}
}
}
公共类形状:EBehaviour{}
公营动物:EBehaviour{}
公共类人口
{
私有void Init()
{
ObjectManager.onObjectInstantiated+=onObjectInstantiated;
}
已安装对象的公共空间(形状)
{
//做些有形状的事
}
}
公营动物
{
私有void Init()
{
ObjectManager.onObjectInstantiated+=onObjectInstantiated;
}
目标(动物)的公共空间
{
//对动物做点什么
}
}
我知道,
public objectmanagervent-onObjectInstantiated()
会抛出一个错误,但我只是有点迷失在如何实现我想要的东西上


有什么提示吗?

首先,您的委托语法非常C#1.0

选择1 您不能以一种特别简单和优雅的方式来实现这一点,因为在C#中,您不能使用开放泛型类型来声明泛型事件。我们能做的最接近的事情就是创建一个对象字典,每个对象都有一个事件,我们可以使用泛型方法访问这个字典

我还假设您打算InstanceObject创建并返回一个新实例。在这里,我还假设一切都是一个具有无参数构造函数的类

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
{
公共类类型事件
{
//我们的事件处理程序将接受类型为T的参数并返回void
针对目标的公共事件行动;
已安装的公共无效对象(T obj)
{
OnObjectInstated?调用(obj);
}
}
私有静态字典_typeMap=新字典();
公共静态TypeEvent ForType(),其中T:class,new()
{
类型t=类型(t);
如果(!_typeMap.ContainsKey(t))
{
_typeMap[t]=新的TypeEvent();
}
将_typeMap[t]作为TypeEvent返回;
}
公共静态T实例化对象(),其中T:class,new()
{
T obj=新的T();
ForType().RAISEOBJECTINSTATITED(obj);
返回obj;
}
}
你可以这样使用它:

        ObjectManager.ForType<Foo>().OnObjectInstantiated += fooInstantiated;
        Foo f = ObjectManager.InstantiateObject<Foo>();
ObjectManager.ForType().OnObjectInstantiated+=fooInstantiated;
Foo f=ObjectManager.InstanceObject();
选择2 如果您同意将ObjectManager本身设置为静态泛型类,则可以大大简化这一过程。注意这意味着您不再只有一个ObjectManager类-
ObjectManager
ObjectManager
现在是具有不同变量的不同类。如果您可以接受,这将使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;
    }
}
公共静态类ObjectManager,其中T:class,new()
{
//我们的事件处理程序将接受类型为T的参数并返回void
对目标的公共静态事件行为;
公共静态T实例化对象()
{
T obj=新的T();
OnObjectInstated?调用(obj);
返回obj;
}
}

首先,您的委托语法非常适合C#1.0

选择1 您不能以一种特别简单和优雅的方式来实现这一点,因为在C#中,您不能使用开放泛型类型来声明泛型事件。我们能做的最接近的事情就是创建一个对象字典,每个对象都有一个事件,我们可以使用泛型方法访问这个字典

我还假设您打算InstanceObject创建并返回一个新实例。在这里,我还假设一切都是一个具有无参数构造函数的类

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
{
公共类类型事件
{
//我们的事件处理程序将接受类型为T的参数并返回void
针对目标的公共事件行动;
已安装的公共无效对象(T obj)
{
OnObjectInstated?调用(obj);
}
}
私有静态字典_typeMap=新字典();
公共静态TypeEvent ForType(),其中T:class,new()
{
类型t=类型(t);
如果(!_typeMap.ContainsKey(t))
{
_typeMap[t]=新的TypeEvent();
}
将_typeMap[t]作为TypeEvent返回;
}
公共静态T实例化对象(),其中T:class,new()
{
T obj=新的T();
ForType().RAISEOBJECTINSTATITED(obj);
返回obj;
}
}
你可以这样使用它:

        ObjectManager.ForType<Foo>().OnObjectInstantiated += fooInstantiated;
        Foo f = ObjectManager.InstantiateObject<Foo>();
ObjectManager.ForType().OnObjectInstantiated+=fooInstantiated;
Foo f=ObjectManager.InstanceObject();
选择2 如果您同意将ObjectManager本身设置为静态泛型类,则可以大大简化这一过程。注意这意味着您不再只有一个ObjectManager类-
ObjectManager
ObjectManager
现在是具有不同变量的不同类。如果您可以接受,这将使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;
    }
}
公共静态类ObjectManager,其中T:class,new()
{
//我们的事件处理程序将接受类型为T的参数并返回void
对目标的公共静态事件行为;
公共静态T实例化对象()
{
T obj=新的T();
OnObjectInstated?调用(obj);
返回obj;
}
}