从类型和实例的字典中获取实例

Vap*_*nus 6 c# generics dictionary types unity-game-engine

我有一个简单的服务管理器ServiceManager,它有两种方法.Create()创建服务的实例.Provide()返回先前已创建的服务.

我有一个基本的实现,但我想知道是否有一个更清洁的方式.这是我的基本实现ServiceManager:

public class ServiceManager : MonoBehaviour
{
    private Dictionary<Type, MonoBehaviour> services = new Dictionary<Type, MonoBehaviour>();

    public void Create<T>() where T : MonoBehaviour
    {
        // Create service
        GameObject serviceObject = new GameObject(typeof(T).Name);
        serviceObject.transform.SetParent(transform); // make service GO our child
        T service = serviceObject.AddComponent<T>(); // attach service to GO

        // Register service
        services.Add(typeof(T), service);
    }

    public T Provide<T>() where T : MonoBehaviour
    {
        return (T)services[typeof(T)]; // notice the cast to T here
    }
}
Run Code Online (Sandbox Code Playgroud)

使用该服务很简单:

public class ServiceTest : MonoBehaviour
{
    private void Start()
    {
        // Creating services
        ServiceManager services = FindObjectOfType<ServiceManager>();
        services.Create<MapService>();
        services.Create<InteractionService>();
    }

    private void Example()
    {
        // Get a service
        ServiceManager services = FindObjectOfType<ServiceManager>();
        MapService map = services.Provide<MapService>();
        // do whatever you want with map
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是关于ServiceManager.Provide().从字典中获取项目后,请注意转换为T. 这种感觉非常不干净,让我想知道我是否遗漏了一些关于泛型如何在C#中工作的东西.还有其他/更好的方法来做我想要完成的事情吗?

Pat*_*man 3

这里没有什么需要改进的。强制转换是必要的,因为字典值类型是 a MonoBehaviour知道它实际上是T,但编译器不知道。你必须通过铸造来告诉你这一点。

你做得很好。