2010-02-05 62 views
4

我有一个方法使用类型对象作为返回类型 - 不好的做法?

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

     return grid; 
    } 

它返回对象的类型的对象。

然后我将对象转换回前一个类型。

var projectModel = new ProjectModel(); 

    projektyModel = (ProjectModel)SetGrid(projectModel); 

这样做的好处是,方法SetGrid可以在整个应用程序中重复使用。

这是一种常见的做法还是应该避免这样做?

回答

13

你可以使用一个通用的方法来代替,并约束类型参数到您的IGrid接口:

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

您应该还是可以调用该方法以完全相同的方式,只是没有投。类型推断应该能够自动的找出你所需要的泛型类型参数:

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

编辑...

至于其他的答案已经提到的,如果你的IGrid对象是引用类型,那么你不要实际上根本不需要从你的方法中返回任何东西。如果你传递引用类型,然后你的方法将更新原来的对象,一个副本:

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

+1为了打我,得出完全相同的结论 – 2010-02-05 09:38:46

+0

两人同时得出同样的结论。 – Sapph 2010-02-05 09:46:30

+0

这是一个更方便的解决方案!作品完美。 thx – user137348 2010-02-05 09:49:33

2

这与泛型更好地完成。您可以对通用typeparam使用约束来保护您的类型安全!

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

然后

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

这里,通用typeparam“T”由编译器通过调用方法的方式实际上是推断出来的。

值得注意的是,在您演示的特定用例中,返回grid可能是不必要的,因为您的原始变量引用将在方法调用后进行适当修改。

5

既然你是传递一个实现iGrid游戏,你可以返回类型一样好改变的iGrid一个类的对象。

而且,因为它是你甚至都不需要再次返回电网中的引用类型。你也可以同样使用:

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

在你说明上面没有必要返回grid的情况。 IGrid实例通过引用传递,因此您的projectModel引用将使用您在SetGrid方法中所做的更改进行更新。

如果你还想返回参数,至少要返回IGrid,因为已经知道参数是IGrid

通常,在静态类型语言/方式编程时,尽可能提供类型信息。

0

你的网格是一个IGrid,为什么不返回IGrid?

2

“这是常见做法还是应该避免这样做?”

这不是常见的做法。你应该避免这样做。

  1. 只修改传入的参数的函数不应该有返回类型。如果导致一些混乱。在当前的C#中,您可以使修改函数成为扩展方法,以提高可读性。

  2. 它会导致返回类型的非必要转换。这是一个性能下降,可能并不明显...但它仍然没有必要,因为你是从一个界面进行投射,即使该对象与传入的参数不同,也会返回该界面。

  3. 返回对象易混淆该功能的用户。假设函数创建了一个副本并返回了一个副本......您仍然想要返回传入的接口,以便使用该函数的人员知道“嘿,我正在获取IGrid回来。”而不是必须弄清楚自己的返回类型。越少,你的队友就会认为这样的事情对你和他们来说越好。

+0

感谢您的解释,但是这种方法的通用版本呢? – user137348 2010-02-05 19:47:59

1

这是一个非常奇怪的例子,因为除了设置一些默认值之外,SetGrid似乎没有做很多其他的事情。您还让代码对自己可以很好地完成的对象执行操作。含义IGridProjectModel可重构这样:

public interface IGrid { 
    // ... 
    public void setDefaults(); 
    // ... 
} 

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

使用这个重构你只需要使用这个执行相同:

myProjectModel.setDefaults(); 

您还可以创建一个抽象基类实现IGrid那实现setDefaults()方法,并让ProjectModel扩展抽象类。


怎么样的SOLID原则是什么?具体来说就是单一责任原则。这个班首先是一个DTO。 - user137348

我正在使用SOLID原理中的Interface Segregation Principle来隐藏类的客户端的实现。即所以客户端不必访问它正在使用的类的内部,否则它违反了Principle of Least Knowledge

Single Responsibility Principle(SRP)只告诉一个类应该只有一个理由去改变这是一个非常模糊的限制,因为你希望它是一个变化可以为狭义和广义。

我相信把一些配置逻辑放在参数类中是可以的,如果它足够小的话。否则,我会把它放在工厂班。我建议这种解决方案的原因是因为IGrid似乎参考PagerHelperSortHelper似乎是IGrid mutators。

所以我觉得很奇怪,你提到的课程是DTO。从纯粹意义上说,DTO除了访问方法(即getter方法)之外不应该有其他逻辑,这使得奇怪的是ProjectModel本身具有对PagerHelperSortHelper的引用,我认为它们可以对它进行变异(即它们是setter)。如果您确实需要SRP,则“帮助者”应该位于创建实例的工厂类中。

+0

固体原理呢?具体来说就是单一责任原则。这个班首先是一个DTO。 – user137348 2010-02-05 19:44:47

+0

谢谢你的辛苦解释!给出一些想法。 – user137348 2010-02-07 21:34:46

相关问题