首页 > 解决方案 > 何时将动态类型与泛型类型一起使用?

问题描述

我对动态关键字的良好做法有疑问。假设我们有一个特定的情况:

public class MyObject
{
    public string Id { get; set; }
    public void DoSth() { /* ... */ }
}

public class Object1 : MyObject { /* ... */ }
public class Object2 : MyObject { /* ... */ }
public class Object3 : MyObject { /* ... */ }

public abstract class MyContainer
{
    public abstract dynamic Get(string id);
}

public class MyContainer<T>: MyContainer where T : MyObject
{
    private Dictionary<string, T> _container;
    public override dynamic Get(string id)
    {
        T result;
        _container.TryGetValue(id, out result);
        return result;
    }
}

public class MyStorage
{
    private MyContainer<Object1> _objects1;
    private MyContainer<Object1> _objects2;
    private MyContainer<Object1> _objects3;

    public Dictionary<Type, MyContainer> GetContainer;

    public MyStorage()
    {
        GetContainer = new Dictionary<Type, MyContainer>() 
        {
            { typeof(Object1), _objects1 },
            { typeof(Object2), _objects2 },
            { typeof(Object3), _objects3 }
        }
    }
}

public static class Program
{
    public static void Main()
    {
        MyStorage storage = new MyStorage();
        // defining a sotrage ...

        Type objectType = //let's say we have it
        string objectId = //let's say we have it

        (storage.GetContainer[objectType].Get(objectId) as MyObject).DoSth();
    }
}

我在“Get”方法中返回一个动态值并将其转换为 MyObject 看起来可以吗?或者也许动态关键字没有问题,但在整个概念中创建这样的存储(保持按类型和标识符获取对象的功能)?

标签: c#generics

解决方案


没有必要在dynamic这里使用。您可以通过使其成为不受约束的泛型并返回 a来简化MyContainer并使其更有用:GetT

  public class MyContainer<T>
  {
    private Dictionary<string, T> _container;
    public T Get(string id)
    {
      T result;
      _container.TryGetValue(id, out result);
      return result;
    }
  }

这样,您不需要抽象类,也不需要任何类型约束,MyContainer可以使用任何类型。如果您出于某种原因确实想限制它,您可以将类定义更改为:

public class MyContainer<T> where T: MyObject

但是,这样做会浪费拥有一个泛型类的全部目的。您不妨制作MyContainer非泛型并将对的任何引用替换TMyObject.


推荐阅读