简体   繁体   中英

How will you use the C# 4 dynamic type?

C# 4 will contain a new dynamic keyword that will bring dynamic language features into C#.

How do you plan to use it in your own code, what pattern would you propose ? In which part of your current project will it make your code cleaner or simpler, or enable things you could simply not do (outside of the obvious interop with dynamic languages like IronRuby or IronPython)?

PS : Please if you don't like this C# 4 addition, avoid to bloat comments negatively.

Edit : refocussing the question.

The classic usages of dynamic are well known by most of stackoverflow C# users. What I want to know is if you think of specific new C# patterns where dynamic can be usefully leveraged without losing too much of C# spirit.

Wherever old-fashioned reflection is used now and code readability has been impaired. And, as you say, some Interop scenarios (I occasionally work with COM).

That's pretty much it. If dynamic usage can be avoided, it should be avoided. Compile time checking, performance, etc.

A few weeks ago, I remembered this article . When I first read it, I was frankly apalled. But what I hadn't realised is that I didn't know how to even use an operator on some unknown type. I started wondering what the generated code would be for something like this:

dynamic c = 10;
int b = c * c;

Using regular reflection, you can't use defined operators. It generated quite a bit of code, using some stuff from a Microsoft namespace. Let's just say the above code is a lot easier to read :) It's nice that it works, but it was also very slow: about 10,000 times slower than a regular multiplication (doh), and about 100 times slower than an ICalculator interface with a Multiply method.

Edit - generated code, for those interested:

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));

The dynamic keyword is all about simplifying the code required for two scenarios:

  • C# to COM interop
  • C# to dynamic language (JavaScript, etc.) interop

While it could be used outside of those scenarios, it probably shouldn't be.

Recently I have blogged about dynamic types in C# 4.0 and among others I mentioned some of its potential uses as well as some of its pitfalls. The article itself is a bit too big to fit in here, but you can read it in full at this address .

As a summary, here are a few useful use cases (except the obvious one of interoping with COM libraries and dynamic languages like IronPython):

  • reading a random XML or JSON into a dynamic C# object. The .Net framework contains classes and attributes for easily deserializing XML and JSON documents into C# objects, but only if their structure is static. If they are dynamic and you need to discover their fields at runtime, they can could only be deserialized into dynamic objects. .Net does not offer this functionality by default, but it can be done by 3rd party tools like jsonfx or DynamicJson
  • return anonymous types from methods. Anonymous types have their scope constrained to the method where they are defined, but that can be overcome with the help of dynamic. Of course, this is a dangerous thing to do, since you will be exposing objects with a dynamic structure (with no compile time checking), but it might be useful in some cases. For example the following method reads only two columns from a DB table using Linq to SQL and returns the result:

     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>(); } 
  • create REST WCF services that returns dynamic data. That might be useful in the following scenario. Consider that you have a web method that returns user related data. However, your service exposes quite a lot of info about users and it will not be efficient to just return all of them all of the time. It would be better if you would be able to allow consumers to specify the fields that they actually need, like with the following URL

     http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age 

    The problem then comes from the fact that WCF will only return to clients responses made out of serialized objects. If the objects are static then there would be no way to return dynamic responses so dynamic types need to be used. There is however one last problem in here and that is that by default dynamic types are not serializable. In the article there is a code sample that shows how to overcome this (again, I am not posting it here because of its size).

In the end, you might notice that two of the use cases I mentioned require some workarounds or 3rd party tools. This makes me think that while the .Net team has added a very cool feature to the framework, they might have only added it with COM and dynamic languages interop in mind. That would be a shame because dynamic languages have some strong advantages and providing them on a platform that combines them with the strengths of strong typed languages would probably put .Net and C# ahead of the other development platforms.

Miguel de Icaza presented a very cool use case on his blog, here (source included):

dynamic d = new PInvoke ("libc");
d.printf ("I have been clicked %d times", times);

If it is possible to do this in a safe and reliable way, that would be awesome for native code interop.

This will also allow us to avoid having to use the visitor pattern in certain cases as multi-dispatch will now be possible

public class MySpecialFunctions
{
  public void Execute(int x) {...}
  public void Execute(string x) {...}
  public void Execute(long x) {...}
}

dynamic x = getx();
var myFunc = new MySpecialFunctions();
myFunc.Execute(x);

...will call the best method match at runtime, instead of being worked out at compile time

I will use it to simplify my code which deals with COM/Interop where before I had to specify the member to invoke, its parameters etc. (basically where the compiler didn't know about the existence of a function and I needed to describe it at compile time). With dynamic this gets less cumbersome and the code gets leaner.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM