【问题标题】:Why can't we use dynamic methods instead for Generic(T) methods为什么我们不能使用动态方法代替 Generic(T) 方法
【发布时间】:2015-12-08 19:39:22
【问题描述】:

我有两个函数定义如下。方法一会动态返回任意类型,方法二会返回泛型类型:

方法一

public dynamic dynamicFun(int n)
        {
            switch (n)
            {
                case 0:
                    return 0;
                case 1:
                    return "N";
                case 2:
                    return 1.3;
                default:
                    return 'v';
            }
        }

方法二:

  public static T genericFun<T>(int n)
        {
            switch (n)
            {
                case 0:
                    return (T)System.Convert.ChangeType(0, Type.GetTypeCode(typeof(T)));
                case 1:
                    return (T)System.Convert.ChangeType("N", Type.GetTypeCode(typeof(T)));
                case 2:
                    return (T)System.Convert.ChangeType(1.3, Type.GetTypeCode(typeof(T)));
                default:
                    return (T)System.Convert.ChangeType('V', Type.GetTypeCode(typeof(T)));
            }
        }

两者都在执行相同的功能。函数调用将在下图中描述:

现在我的问题是;

  • 这两种方法有什么区别?
  • 哪些地方可以使用动态方法,哪些地方可以使用泛型?
  • 与动态相比,通用有什么优势吗?

【问题讨论】:

  • is there any advantage for generic over dynamic? 它给你编译检查
  • dynamic 比较慢,因为它每次都进行运行时绑定。
  • 有一个非常简单的酸性测试可用。如果您在泛型方法中使用 switch() 或 typeof() ,那么它不应该是泛型的可能性很大。动态方法的简洁性是另一个优势。
  • @HansPassant typeof() 本身没问题。想想在字典中缓存。
  • 你的 dynamicFun 应该返回对象,而不是动态的。 dynamicFun 不使用动态的任何特性。让调用者决定是否要使用动态。

标签: c# .net function generics dynamic


【解决方案1】:

为什么我们不能使用动态方法而不是 [of] Generic(T) 方法?

在我看来你可以,你的例子和运行时值证明了。但是您对示例的思考存在一个固有的错误:您知道在您的泛型方法中返回的是什么类型,所以您以这种方式实例化它。如果我做了var genericCase1 = genericFun&lt;int&gt;(1),会返回什么?可能会抛出异常,因为“N”不是整数。

这两种方法有什么区别?

动态在运行时确定,而泛型在编译时解决。

哪些地方可以使用动态方法,哪些地方可以使用泛型?

我猜你可以在任何地方使用方法。您使用一个而不是另一个的原因实际上取决于您所处的情况。如果您不知道在撰写本文时将返回给您的确切类型,那么请走动态路线。当您知道要处理具有特定方法的几个不同的基类/超类时,您可以使用它,并且您想要使用该方法,但您不关心从动态方法返回哪个派生类。

泛型可用于避免为同一功能编写大量重载。如果你知道你想对许多不同的事情执行相同的操作,那么创建一个通用方法,并在你的写作过程中传递你想要做的事情的类型。使用类型约束也非常棒,因为现在您可以限制哪些类型能够调用此泛型方法,并在编译时发现任何问题。

通用比动态有什么优势吗?

正如其他人在 cmets 中所说,存在时间问题,一种方法可能比另一种方法花费更长的时间,但我认为其中的一部分将取决于实现的方法,以及 JIT 与编译器必须做的工作量.

泛型还可以实现类型安全和减少错误,因为它们是在编译时解决的。泛型也可能更容易维护,因为没有那么多“魔法”发生。

您可能应该谨慎使用动态,因为尽管它们很强大,但使用不当可能会导致许多不眠之夜的调试。


如果我在这方面有任何错误,请有人纠正我。和我们大多数人一样,我也在学习,如果我目前的理解有任何问题,我将不胜感激。

【讨论】:

    【解决方案2】:

    泛型的一大优点是您可以指定 T 的类型。 void doSomething&lt;T&gt; () where T : abstractParentClass

    【讨论】:

      猜你喜欢
      • 2021-05-12
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多