C#Generics,寻求帮助以理解样本

时间:2017-07-20 09:39:21

标签: c# generics

我试图理解编写实现泛型的现有代码片段,因此它设置了一个通用字典,然后将项目添加到字典中,其中键是类型,值是委托

private readonly Dictionary<Type, Func<actionType, Task>> requestedActions;

private void AddAction<T>(Func<T, Task> action) where T : actionType
{
    this.requestedActions[typeof(T)] = (request) => action((T)request);
}

this.AddAction<AddItem>(this.HandleAdd);
this.AddAction<UpdateItem>(this.HandleUpdate);
this.AddAction<DeleteItem>(this.HandleDelete);

 private Task HandleAdd(AddItem message)
    {
         .....
    }

然后当收到某个动作时,它会执行相关的委托

 public bool ProcessData(ItemMessage request)
 {
    Func<ItemMessage, Task> requestAction;
    if (this.requestedActions.TryGetValue(requestType, out requestAction))
    {
          requestAction(request).Await();
    }                   

 }

为什么这种方法会优先于/类似于actionType上的switch语句,就好像添加了新类型一样,你仍然需要将新类型添加到字典中并实现新的处理函数。我试图理解在这个例子中使用泛型所得到的东西??

switch (actionType)
      {
          case AddItem:
              HandleAdd();
              break;
          case UpdateItem:
              HandleUpdate();
              break;
      ...
      }

3 个答案:

答案 0 :(得分:1)

Generic示例允许您动态添加处理程序(在运行时),而switch语句基本上是&#34;烘焙&#34;进入代码。

这是我能想出的原因的主要例子。

此外,通用示例看起来很花哨。

答案 1 :(得分:0)

在不知道使用场景的情况下很难判断哪种方法更好,但是在最初的示例中,您可以从数据库中提取和序列化数据,而无需为添加switch语句而烦恼每次你介绍一个新的动作。看起来通过使用泛型来节省开发时间。

我们还要检查使用此示例与switch语句相比的速度差异。如果您在函数调用时已准备好类型,则字典时间检索为O(1)。这与switch语句的检索相同,而不必为交换机烦恼。

答案 2 :(得分:0)

当您使用通用数据结构(字典)作为示例时,此问题与多态而非泛型有关。

正如您已经被告知的那样,切换是不好的,因为如果您想添加另一个案例,您必须修改这段代码。切换通常是代码气味,表明应该使用多态。

在这种情况下使用开关违反了开/关原则(SOLID)。简而言之,这个原则说,应该打开代码进行更改,但是关闭以进行修改。您提供的示例遵循此规则。如果您想要其他操作,则无需触摸此代码,只需添加另一个Task类即可。使用开关,您需要 MODIFY 现有代码。

我希望这有帮助!