何时将动态类型与泛型类型一起使用?

时间:2018-09-17 17:16:57

标签: c# generics

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

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看起来还可以吗?也许动态关键字没有问题,但是在整个概念上创建这样的存储(保持按类型和标识符获取对象的功能)?

1 个答案:

答案 0 :(得分:0)

这里不需要使用dynamic。您可以简化MyContainer并使其更有用,方法是使其成为不受约束的泛型,并使Get返回T

  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设为非泛型,并用T替换对MyObject的所有引用。