Using object type as return type is bad practice?

I have a method

private object SetGrid(IGrid grid) { grid.PagerHelper.SetPage(1, 10); grid.SortHelper.SetSort(SortOperator.Ascending); grid.PagerHelper.RecordsPerPage = 10; return grid; } 

which returns an object of type object.

Then I returned the object back to the previous type.

  var projectModel = new ProjectModel(); projektyModel = (ProjectModel)SetGrid(projectModel); 

By acquiring this method, the SetGrid method can be reused in the application.

Is this a common practice or should I avoid it?

+4
source share
7 answers

Instead, you can use the general method and restrict the type argument to your IGrid interface:

 private T SetGrid<T>(T grid) where T : IGrid { grid.PagerHelper.SetPage(1, 10); grid.SortHelper.SetSort(SortOperator.Ascending); grid.PagerHelper.RecordsPerPage = 10; return grid; } 

You can still call the method in the same way as without an actor. Type inference should be able to automatically determine the required generic argument for you:

 var projectModel = new ProjectModel(); projektyModel = SetGrid(projectModel); 

EDIT ...

As the other answers mentioned, if your IGrid objects are reference types, you actually don't need to return anything from your method at all. If you pass a reference type, your method will update the source object, not a copy of it:

 var projectModel = new ProjectModel(); // assume that ProjectModel is a ref type projektyModel = SetGrid(projectModel); bool sameObject = object.ReferenceEquals(projectModel, projektyModel); // true 
+13
source

Since you are passing a class object that implements IGrid, you can simply change the return type to IGrid.

Also, since this is a reference type, you don't even need to return the grid again. You can also use this:

 var projectModel = new ProjectModel(); SetGrid(projectModel); 
+5
source

This is best achieved with generics. You can use the type constraint to keep your type safe!

 private T SetGrid<T>(T grid) where T : IGrid { grid.PagerHelper.SetPage(1, 10); grid.SortHelper.SetSort(SortOperator.Ascending); grid.PagerHelper.RecordsPerPage = 10; return grid; } 

and then

 var projectModel = new ProjectModel(); projectModel = SetGrid(projectModel); 

Here, the generic type T "type is actually inferred by the compiler as you call the method.

It is worth noting that in the specific use case that you demonstrated, the grid return is probably not needed, since the original reference to the variable will be changed accordingly after the method is called.

+2
source

In the above example, there is no need to return grid . The IGrid instance IGrid passed by reference, so the projectModel link will be updated with the changes you made to the SetGrid method.

If you still want to return the argument, return at least IGrid , since it is already known that the argument is IGrid .

In general, provide as much type information as you can when programming in a statically typed language / style.

+2
source

"Is this a common practice or should I avoid it?"

This is not a common practice. You should avoid this.

  • Functions that only modify the passed parameter should not have return types. If this causes some confusion. In current C #, you can make a modifier function an extension method for better readability.

  • This results in an unnecessary return type. This is a performance degradation that might not be noticeable ... but it is still unnecessary, since you discard the interface, return that interface even if the object is different from the passed parameter.

  • The returned object confuses users of this function. Suppose a function creates a copy and returns a copy ... you still want to return the interface passed so that people using this function know: "Hey, I am returning an IGrid." instead of figuring out which type is being returned to your account. The less you make your teammates think about such things, the better for you and for them.

+2
source

This is a very strange example, because SetGrid does not seem to perform many other tasks than setting some default values. You also allow the code to manipulate the object, which can very well do it on its own. The value of IGrid and ProjectModel can be reorganized into this:

 public interface IGrid { // ... public void setDefaults(); // ... } public class ProjectModel : IGrid { // ... public void setDefaults() { PagerHelper.SetPage(1, 10); SortHelper.SetSort(SortOperator.Ascending); PagerHelper.RecordsPerPage = 10; } // ... } 

Using this refactoring, you need to do the same with this:

 myProjectModel.setDefaults(); 

You can also create an abstract base class that implements IGrid , which implements the setDefaults() method, and ProjectModel extends the abstract class.


What about SOLID principles? Specifically, the principle of shared responsibility. The class is primarily similar to the DTO. - user137348

I am implementing the principle of segment separation from SOLID principles here to hide the implementation from the class client. That is, therefore, the client does not need to access the internal functions of the class used, otherwise this is a violation of the principle of least knowledge .

The Single Responsibility Principle (SRP) only says that a class should have only one reason for change, which is a very vague restriction from the moment of change that can be as narrow and wide as you want.

I believe that it’s quite normal to insert some configuration logic into the parameter class if it is small enough. Otherwise, I would put all this in a factory class. The reason I propose this solution is because IGrid seems to reference PagerHelper and SortHelper , which seem to be IGrid for IGrid .

Therefore, it seemed strange to me that you note that the class is a DTO . From a purist sense, a DTO should not have logic except accessories (i.e. getter methods), which makes it strange that ProjectModel itself has links to PagerHelper and SortHelper , which, I believe, can mutate (i.e. retailers). If you really want SRP, the helpers should be in the factory class that creates the IGrid / ProjectModel instance.

+1
source

Your grid is an IGrid, why not bring back an IGrid?

0
source

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


All Articles