thi*_*ing 21 c# dynamic c#-4.0
C#4将包含一个新的dynamic关键字,它将动态语言功能引入C#.
您打算如何在自己的代码中使用它,您会提出什么样的模式?您当前项目的哪一部分将使您的代码更清晰或更简单,或启用您可能根本无法做到的事情(除了与IronRuby或IronPython等动态语言的明显互操作之外)?
PS:如果你不喜欢这个C#4,请避免负面评论.
编辑:重新发现问题.
动态的经典用法是大多数stackoverflow C#用户所熟知的.我想知道的是,如果你想到特定的新C#模式,可以有效地利用动态而不会失去太多的C#精神.
Tho*_*rin 12
现在使用老式反射,代码可读性受损.而且,正如你所说,一些Interop场景(我偶尔会使用COM).
这就是它.如果dynamic可以避免使用,则应避免使用.编译时间检查,性能等
几个星期前,我记得这篇文章.当我第一次看到它时,坦率地说,我已经做好了准备.但我没有意识到的是,我不知道如何在某种未知类型上使用运算符.我开始想知道生成的代码会是什么样的:
dynamic c = 10;
int b = c * c;
Run Code Online (Sandbox Code Playgroud)
使用常规反射,您不能使用已定义的运算符.它使用Microsoft命名空间中的一些东西生成了相当多的代码.让我们说上面的代码更容易阅读:)它很好用它,但它也很慢:比常规乘法(doh)慢大约10,000倍,比ICalculator带有Multiply 的接口慢大约100倍方法.
编辑 - 为感兴趣的人生成代码:
if (<Test>o__SiteContainer0.<>p__Sitea == null)
<Test>o__SiteContainer0.<>p__Sitea =
CallSite<Func<CallSite, object, object, object>>.Create(
new CSharpBinaryOperationBinder(ExpressionType.Multiply,
false, false, new CSharpArgumentInfo[] {
new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null),
new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
b = <Test>o__SiteContainer0.<>p__Site9.Target(
<Test>o__SiteContainer0.<>p__Site9,
<Test>o__SiteContainer0.<>p__Sitea.Target(
<Test>o__SiteContainer0.<>p__Sitea, c, c));
Run Code Online (Sandbox Code Playgroud)
最近我发表了关于C#4.0动态类型的博客,其中我提到了它的一些潜在用途以及它的一些陷阱.文章本身有点太大,不适合这里,但你可以在这个地址完整阅读.
总结一下,这里有一些有用的用例(除了明显的COM库和动态语言如IronPython之外):
从方法返回匿名类型.匿名类型的范围受限于定义它们的方法,但可以借助动态来克服.当然,这是一件危险的事情,因为您将使用动态结构公开对象(没有编译时检查),但在某些情况下它可能很有用.例如,以下方法使用Linq to SQL从DB表中只读取两列,并返回结果:
public static List<dynamic> GetEmployees()
{
List<Employee> source = GenerateEmployeeCollection();
var queyResult = from employee in source
where employee.Age > 20
select new { employee.FirstName, employee.Age };
return queyResult.ToList<dynamic>();
}
Run Code Online (Sandbox Code Playgroud)创建返回动态数据的REST WCF服务.这在以下场景中可能很有用.假设您有一个返回用户相关数据的Web方法.但是,您的服务会暴露很多关于用户的信息,并且无法始终全部返回所有这些信息.如果您能够允许消费者指定他们实际需要的字段会更好,例如使用以下URL
http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age
Run Code Online (Sandbox Code Playgroud)
问题在于WCF只返回客户端对序列化对象做出的响应.如果对象是静态的,则无法返回动态响应,因此需要使用动态类型.然而,这里存在最后一个问题,即默认情况下动态类型不可序列化.在文章中有一个代码示例,展示了如何克服这个问题(再次,由于它的大小,我不会在这里发布).
最后,您可能会注意到我提到的两个用例需要一些解决方法或第三方工具.这让我觉得虽然.Net团队为框架添加了一个非常酷的功能,但他们可能只是将它与COM和动态语言相互补充.这将是一种耻辱,因为动态语言有一些很强的优势,并结合他们具有很强的类型语言的优势很可能把.NET和C#领先于其他开发平台的平台上为他们提供.
我将使用它来简化处理 COM/Interop 的代码,在此之前我必须指定要调用的成员、其参数等(基本上,编译器不知道函数的存在,而我需要描述它)在编译时)。通过动态,这变得不再那么麻烦,代码也变得更精简。