Is this bad form excessive overload for a method or constructor in C #?

I am writing code for Unity using C #. I am currently dealing with several smaller classes and structures to quickly serialize a randomly generated map. However, I am dealing with several constructors that also take some of these smaller classes and structures as parameters.

In the past, I usually tried to consider options when setting up my methods and constructors. Although this practice was called into question, no one was able to give me a plausible reason why I should not do it this way.


Consider the following class and structures:

public class Tile { public GridCoordinates position; public TileCode prefabID; } public struct GridCoordinates { public int x; public int y; } public struct TileCode { public int categoryID; public int individuaID; } 

As a rule, when creating constructors, I would use all alternatives to struct and int . Tile will look something like this:

 public class Tile { public GridCoordinates position; public TileCode prefabID; public Tile(TileCode prefabID, GridCoordinates position) { this.prefabID = new TileCode(prefabID); this.position = new GridCoordinates(position); } public Tile(TileCode prefabID, int xPosition, int yPosition) { this.prefabID = new TileCode(prefabID); position = new GridCoordinates(xPosition, yPosition); } public Tile(int typeID, int individualID, GridCoordinates position) { prefabID = new TileCode(typeID, individualID); this.position = new GridCoordinates(position); } public Tile(int typeID, int individualID, int xPosition, int yPosition) { prefabID = new TileCode(typeID, individualID); position = new GridCoordinates(xPosition, yPosition); } 

I do this to increase efficiency. It takes me a little extra time to write additional constructors / methods in tandem with the first constructor / method, and I find it sometimes useful when I later want to use the constructor / method in a way that I did not initially use expected.

The only problem that was raised earlier is confusion. I feel this is not a problem, as my organization and comments clearly distinguish each option.


Ultimately, I am concerned that there may be other problems that my teachers and peers did not know about. I am currently considering expanding into a much larger project, and now it would be much easier to paint my behavior than fixing it later.

As for me, if I provide excessive alternative constructors or methods for my classes?

  • I am not so worried about aesthetics and standards, although a good answer might mention them. I try to follow C # standards, but not always.
  • I have problems with potential resource requirements that may arise, so a good answer can confirm any problems that may arise there.
  • As I mentioned, I am writing for Unity. I know that although most C # conventions are standard, there are several options for working with Unity. Bonus points to solve this problem in particular, but a good answer would be to use the language as a whole.
+6
source share
2 answers

The problem with your approach is that it violates the Do not Repeat Yourself principle (also known as DRY). Adding “convenience constructors” that pass parameters depending on dependencies increases the code connection between the two modules (in particular, the control communication ), which, as a rule, should be avoided.

However, there is one situation where you prefer convenience constructors: this happens when GridCoordinates and TitleCode considered as details of the Title implementation, and therefore should not be displayed. If so, you should only open the last constructor and remove all constructors that rely on GridCoordinates and TitleCode from the public interface of your class.

+2
source

I do not see anything wrong, defining as many overloads as you see fit, if they are clearly documented. I do not know any good practice or principle recommending the opposite. The obvious drawback is, obviously, the increase in code maintenance costs; documentation and testing when you need to change something.

Which causes my main problem with the code you posted; what I really find is troubling in your code, and I would never write like that because I have so many independent implementations. If you later decide to change the logic of the constructor, you will have to change it everywhere, and this will be very vulnerable. I would reorganize the code to use the chain of constructors and implement all the design logic in one single overload and just translate the chain / delegate all the other constructors to one.

All that has been said, my personal opinion is that you should support as many overloads as possible, where the arguments are as "typified" as possible regarding your business domain. By this I mean:

 public Foo(int i, int j, int k, int n) { ... } 

It is terribly error prone. The call to Foo(j, i, k, n) is quite plausible, and it is very difficult to find it in a large code base after errors appear, possibly due to the call stack.

However, a signature like:

 public Foo(Bar bar, Blah blah) 

This is much safer because the type system and compiler can help you.

+2
source

Source: https://habr.com/ru/post/1013068/


All Articles