When should one use dynamic keyword in c# 4.0?.......Any good example with dynamic keyword in c# 4.0 that explains its usage....
问题:
回答1:
Dynamic should be used only when not using it is painful. Like in MS Office libraries. In all other cases it should be avoided as compile type checking is beneficial. Following are the good situation of using dynamic.
- Calling javascript method from Silverlight.
- COM interop.
- Maybe reading Xml, Json without creating custom classes.
回答2:
How about this? Something I've been looking for and was wondering why it was so hard to do without 'dynamic'.
interface ISomeData {}
class SomeActualData : ISomeData {}
class SomeOtherData : ISomeData {}
interface ISomeInterface
{
void DoSomething(ISomeData data);
}
class SomeImplementation : ISomeInterface
{
public void DoSomething(ISomeData data)
{
dynamic specificData = data;
HandleThis( specificData );
}
private void HandleThis(SomeActualData data)
{ /* ... */ }
private void HandleThis(SomeOtherData data)
{ /* ... */ }
}
You just have to maybe catch for the Runtime exception and handle how you want if you do not have an overloaded method that takes the concrete type.
Equivalent of not using dynamic
will be:
public void DoSomething(ISomeData data)
{
if(data is SomeActualData)
HandleThis( (SomeActualData) data);
else if(data is SomeOtherData)
HandleThis( (SomeOtherData) data);
...
else
throw new SomeRuntimeException();
}
回答3:
As described in here dynamics can make poorly-designed external libraries easier to use: Microsoft provides the example of the Microsoft.Office.Interop.Excel assembly. And With dynamic, you can avoid a lot of annoying, explicit casting when using this assembly.
Also, In opposition to @user2415376 ,It is definitely not a way to handle Interfaces since we already have Polymorphism implemented from the beginning days of the language!
You can use
ISomeData specificData = data;
instead of
dynamic specificData = data;
Plus it will make sure that you do not pass a wrong type of data object instead.
回答4:
Check this blog post which talks about dynamic keywords in c#. Here is the gist:
The dynamic keyword is powerful indeed, it is irreplaceable when used with dynamic languages but can also be used for tricky situations while designing code where a statically typed object simply will not do.
Consider the drawbacks:
There is no compile-time type checking, this means that unless you have 100% confidence in your unit tests (cough) you are running a risk.
The dynamic keyword uses more CPU cycles than your old fashioned statically typed code due to the additional runtime overhead, if performance is important to your project (it normally is) don’t use dynamic.
Common mistakes include returning anonymous types wrapped in the dynamic keyword in public methods. Anonymous types are specific to an assembly, returning them across assembly (via the public methods) will throw an error, even though simple testing will catch this, you now have a public method which you can use only from specific places and that’s just bad design.
It’s a slippery slope, inexperienced developers itching to write something new and trying their best to avoid more classes (this is not necessarily limited to the inexperienced) will start using dynamic more and more if they see it in code, usually I would do a code analysis check for dynamic / add it in code review.
回答5:
It is definitely a bad idea to use dynamic in all cases where it can be used. This is because your programs will lose the benefits of compile-time checking and they will also be much slower.
回答6:
I will like to copy an excerpt from the code project post, which define that :
Why use dynamic?
In the statically typed world, dynamic gives developers a lot of rope to hang themselves with. When dealing with objects whose types can be known at compile time, you should avoid the dynamic keyword at all costs. Earlier, I said that my initial reaction was negative, so what changed my mind? To quote Margret Attwood, context is all. When statically typing, dynamic doesn't make a stitch of sense. If you are dealing with an unknown or dynamic type, it is often necessary to communicate with it through Reflection. Reflective code is not easy to read, and has all the pitfalls of the dynamic type above. In this context, dynamic makes a lot of sense.[More]
While Some of the characteristics of Dynamic keyword are:
- Dynamically typed - This means the type of variable declared is decided by the compiler at runtime time.
- No need to initialize at the time of declaration.
e.g.,
dynamic str;
str=”I am a string”; //Works fine and compiles
str=2; //Works fine and compiles
Errors are caught at runtime
Intellisense is not available since the type and its related methods and properties can be known at run time only. [https://www.codeproject.com/Tips/460614/Difference-between-var-and-dynamic-in-Csharp]
回答7:
Here is a recent case in which using dynamic
was a straightforward solution.
I had ported some code from VB6 into C#. This ported code still needed to call other methods on VB6 objects via COM interop.
The classes needing to be called looked like this:
class A
{
void Foo() {...}
}
class B
{
void Foo() {...}
}
(i.e., this would be the way the VB6 classes looked in C# via the COM interop; specifically the COM-callable wrapper which was autogenerated).
Since A and B are independent of each other you can't cast one to the other, and they have no common base class (COM doesn't support that AFAIK and VB6 certainly didn't. And they did not implement a common interface - see below).
The original VB6 code which was ported did this:
' Obj must be either an A or a B
Sub Bar(Obj As Object)
Call Obj.Foo()
End Sub
Now in VB6 you can pass things around as Object
and the runtime will figure out if those objects have method Foo()
or not. But in C# a literal translation would be:
// Obj must be either an A or a B
void Bar(object Obj)
{
Obj.Foo();
}
Which will NOT work. It won't compile because object
does not have a method called "Foo", and C# being typesafe won't allow this.
So the simple "fix" was to use dynamic
, like this:
// Obj must be either an A or a B
void Bar(dynamic Obj)
{
Obj.Foo();
}
This defers type safety until runtime, but assuming you've done it right works just fine.
I wouldn't endorse this for new code, but in this situation (which I think is not uncommon judging from other answers here) it was valuable.
Alternatives considered:
Using reflection to call Foo(). Probably would work, but more effort and less readable.
Modifying the VB6 library wasn't on the table here, but maybe there could be an approach to define A and B in terms of a common interface, which VB6 and COM would support. But using dynamic was much easier.
Note: This probably will turn out to be a temporary solution. Eventually if the remaining VB6 code is ported over then a proper class structure can be used and static compile time checking would replace the use of dynamic
. I admit that such a hopeful future made me more comfortable using this approach which could have some maintenance risk.