C#4.0“动态”关键字是否会使泛型多余?

时间:2009-05-06 06:36:17

标签: c# .net generics reflection dynamic

我对C#(C#4 dynamic keyword - why not?)中的动态功能感到非常兴奋,特别是因为在我的代码的某些库部分中我使用了很多反射。

我的问题有两个:

1。 “动态”取代泛型,如下面的情况?

泛型方法:

public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) {

        //test object is not null, regardless of its Type
        if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) {
            //do something
        }
    }

动态方法(??):

public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) {

        //test object is not null, regardless of its Type?? but how?
        if (ObjToTest != null) {
            //do something
        }
    }

2。 “动态”现在是否允许方法返回匿名类型,如下面的情况?:

 public static List<dynamic> ReturnAnonymousType() {
        return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList();
    }
酷,欢呼声

修改

仔细考虑了我的问题,并根据答案,我看到我完全搞砸了主要的通用/动态问题。他们的确完全不同。所以,是的,感谢所有的信息。

虽然第2点怎么样?

5 个答案:

答案 0 :(得分:17)

回答你的问题。

  • 泛型为您提供“算法重用” - 您可以编写独立于数据类型的代码。 dynamic关键字不会执行与此相关的任何操作。我定义List<T>然后我可以将它用于字符串列表,整数等...
  • 类型安全:整个编译时检查辩论。动态变量不会通过编译时警告/错误提醒您,如果您犯了错误,如果您尝试调用的方法丢失,它们将在运行时爆炸。静态与动态类型辩论
  • 性能:泛型可以使用值类型提高算法/代码的性能一个重要的数量级。它可以防止整个拳击 - 拆箱周期花费我们预先仿制药。 Dynamic也没有为此做任何事情。

dynamic关键字会给你的是

  • 更简单的代码(当您与Excel进行互操作时,可以说..)您不需要指定类的名称或对象模型。如果调用正确的方法,则运行时将负责调用该方法(如果该方法当时存在)。即使未定义方法,编译器也可让您逃脱。但是,这意味着这将比进行编译器验证/静态类型的方法调用慢,因为CLR必须在进行动态var字段/方法调用之前执行检查。
  • 动态变量可以在不同的时间点保存不同类型的对象 - 您不会绑定到特定的族或对象类型。

答案 1 :(得分:16)

dynamic可能会简化有限数量的反射场景(您事先知道成员名称,但没有接口) - 特别是,它可能有助于泛型运算符(although other answers exist) - 但除了通用运算符技巧之外,与泛型几乎没有交叉。

泛型允许您(在编译时)知道您正在使用的类型 - 相反,dynamic不会关注类型。 特别是 - 泛型允许您指定和证明关于类型的许多条件 - 即它可能实现某个接口,或者具有公共无参数构造函数。 dynamic也没有帮助:它不支持接口,而不仅仅是不关心接口,这意味着我们甚至无法使用{{查看显式接口实现1}}。

此外,dynamic实际上是dynamic的一个特例,所以拳击发挥作用,但有一个疏忽。

实际上,您应该将object的使用限制在少数情况下:

  • COM interop
  • DLR interop
  • 也许一些轻松的鸭子打字
  • 可能一些通用运算符

对于所有其他情况,可以使用泛型和常规C#。

答案 2 :(得分:8)

要回答您的第一个问题,泛型会在运行时解析编译时的动态类型。因此,类型安全性和速度存在明显差异。

答案 3 :(得分:6)

动态类和泛型是完全不同的概念。使用泛型,您可以在编译时定义类型。它们不会改变,它们不是动态的。您只需将“占位符”放在某个类或方法中,以使调用代码定义类型。

动态方法在运行时定义。那里没有编译时类型安全。动态类与使用反射的字符串名称具有对象引用和调用方法类似。

答案 4 :(得分:3)

回答第二个问题:您可以在C#3.0中返回匿名类型。将类型转换为对象,返回它并使用反射来访问它的成员。动态关键字只是语法糖。