Why is using dynamic something to be avoided?

14

My company works with development, it is a company practice for all codes to be reviewed by another person before they are approved in pull request .

Generally my codes have only a few details to change, but this time the reviewer commented on a code snippet where I used dynamic to assign the type of return in the method on the grounds that this is a bad practice and would not accept that PR for that.

In the specific example it was in a method that could receive both numbers and strings , concatenating the result in cases of string or adding in cases of numbers, then the output had type that depended on the input type.

So I had 3 questions:

  • Why is dynamic considered a practice to avoid?
  • Is there anything that can replace use with the same effect?
  • Which case where dynamic is required?
asked by anonymous 10.05.2017 / 18:36

4 answers

21

Never accept something that says that a practice is good or bad, that is of no use except for the person to "impose" his will. If the person explains why this is no longer a mere practice and happens to be relevant information for you to make better decisions.

  

Why is using dynamic a practice to be avoided?

It is not a bad practice, it should be used where it is needed. It should not be used where there is a better solution, like all language mechanisms.

dynamic basically turns off type checking and it is your problem accessing existing members in the object, if that is what you need, use it.

Further Important Reading . And too .

  

Is there anything that can replace use with the same effect?

Depends on what you need. Equal effect not.

  • There are cases that a object in place, generalizes type, but does not turn off type checking, so it can only access members of object , even if the object has other members. If you want to access these members you should cast . Not very interesting in most cases.

  • You can use generics (concept). Most of what you think of dynamic can be best solved with this mechanism.

  • If you just do not want to type the data type then just use % with_% / a>.

  • Use a var , syntax may not be the most pleasant, but essentially the same semantics.

  • Likely solution for your case : If it is a parameter of a method that can work with unrelated types you should use # and have different methods for different operations. Such comments seem to be the case. If it is the return, as there is no overhead in this case you have to create a method with a different name. Returning different types means that the methods are different. If you have Dictionary inside the method to decide what to do, surely the solution is to create an overload of the method.

  • If you really only want to be able to receive objects from the same hierarchy, it may be useful to only use polymorphism .

  • There are more crazy solutions that I will not even mention.

Codes showing this .

  

Where is the use of dynamic needed?

Whenever you have no control over the structure of the object.

It was created primarily for interoperability with external applications and codes, such as COM and other "dynamic" languages that run in CLR .

Or it is used for objects that need to be structured (not just created) at runtime, for example creating a table-based class from a database that you do not know ( practical example ). Another common example is to get a JSON that you do not know how it will come ( practical example ).

Another practical example .

It has nothing to do with taste, it has to do with need. In a static language it is not idiomatic to leave the dynamic typing. Abuse of if is something considered bad in C #. Using where the best solution is no problem.

    
10.05.2017 / 18:47
18

Basically, it should not be avoided. You have to know how to use and when to use. This story of being "good practice" or "bad practice" is mostly an artifice used to impose rules without having to base what you are talking about.

  

Why does dynamic be considered a practice to avoid?

Only those who have told you this can answer this question. But it is likely that this is because, using dynamic , everything is resolved at runtime and not compiled, so it is much easier to do some bullshit and end up crashing the application.

Changing in kids, you simply "throw away" one of the great advantages of static languages is to know beforehand all (possible) existing members of an object.

A small example:

dynamic pessoa = new { Nome = "jbueno" };
var n = pessoa.nome;

This code compiles normally, but it bursts a run-time error because the nome property does not exist in pessoa .

  

Is there anything that can replace use with the same effect?

If by "effect" you mean dynamicity: the answer is no. And if this is really necessary I would even tell you that you are probably using the wrong language.

For other cases it is possible to give you some tips knowing the real need. Citing all possibilities is impractical.

  

What case where the use of dynamic is required?

Depends a little. It is necessary whenever you can not know the structure of the object beforehand.

A real example would be to make a request to a webservice whose return might have two completely different structures.

Other cases are likely to be most useful. I find it difficult that the creation of this resource was to solve cases like this example.

{ "sucesso": "true" };
{ "erro": "Algo deu errado" };
    
10.05.2017 / 18:47
7

Asking why a feature is something to be avoided is like asking why using a tool should be avoided. And you'll never hear anyone asking something like "why should I avoid using star-key".

Using a feature is only a bad practice when it is used as the right solution to the wrong problem, and vice versa.

In your case, it seems to me from the comments that you want to use dynamic to vary the return format of a method, according to the input. This is bad practice because:

  • ensures that with each new type of return you have to deal with, it increases the complexity of the code and its analysis;
  • C # is a strongly typed language - but by using dynamic as you propose, you create a point on the system in which determining a type becomes difficult.

Talk to your reviewer and try to understand his vision, as he may still have a different understanding of the understanding of each person who responds here.

    
10.05.2017 / 18:52
6

More a different perception.

By its very nature dynamic can be used for purposes other than its purpose. So it is bad practice to use it when there is clearly a better alternative available. And what is the "best alternative"? This is where the prohibition arises "it is bad practice to use it".

But why does dynamic exist then? Is it "one more" bug from the .NET team?

The answer begins to be drawn since it is known that dynamic type was introduced in the .NET 4.0 update package. More precisely, as part of the Dynamic Language Runtime (DLR).

Well, then it was introduced in a late version of .NET, so it's not legacy. Definitely to supply something. Here comes the old presumption that we should have good arguments to enter into a big fight.

The type dynamic addresses the lack / interoperability difficulty of .NET and simplifies complex codes, including:

  • Interoperability with implementations of several dynamic languages in .NET (Iron), such as IronRuby, IronPython and IronScheme, although they are abandoned or outdated at the moment

  • Interoperability with objects COM , such as omitting multiple type conversions and empty parameter passing (MissingValue ) - eg: Office libraries;

  • Complex Type Manipulation without having to create multiple custom classes, such as XML and JSON. Ex.:

    public getFullName(String json){
        dynamic data = JObject.Parse(json);
    
        return String.Join(" ", new string[] {
            data.results.info.name.first, data.results.info.name.last
        });
    }
    
  • Alternative to using Reflections complex.

But it's worth noting that it should be avoided in several cases, the most common being:

  • means of escape of conversions between data types;
  • means of escape from conversions to / from reusable classes or pertinent to business logic;
  • alternative to polymorphisms, mainly to unify methods with overloads;
  • alternative to strongly-typed static type variables resolved at compile time, but not implicit type or unnamed types, ie, all that is not declared as <tipo> <nome_var>; , mainly substituting anonymous types ( var a = {"b": 1}; -> dynamic a = {"b": 1} ).
10.05.2017 / 23:33