C# 使用类型对象作为返回类型-错误的做法?
我有办法C# 使用类型对象作为返回类型-错误的做法?,c#,oop,methods,C#,Oop,Methods,我有办法 private object SetGrid(IGrid grid) { grid.PagerHelper.SetPage(1, 10); grid.SortHelper.SetSort(SortOperator.Ascending); grid.PagerHelper.RecordsPerPage = 10; return grid; } 返回object类型的对象 然后我将对象强制转换回以前
private object SetGrid(IGrid grid)
{
grid.PagerHelper.SetPage(1, 10);
grid.SortHelper.SetSort(SortOperator.Ascending);
grid.PagerHelper.RecordsPerPage = 10;
return grid;
}
返回object类型的对象
然后我将对象强制转换回以前的类型
var projectModel = new ProjectModel();
projektyModel = (ProjectModel)SetGrid(projectModel);
这样做的好处是,SetGrid方法可以在整个应用程序中重用
这是一种常见的做法还是我应该避免这样做 您可以改用泛型方法,并将类型参数约束到您的
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;
}
编辑…
正如其他答案所提到的,如果您的IGrid
对象是引用类型,那么您实际上根本不需要从方法返回任何内容。如果传递引用类型,则方法将更新原始对象,而不是其副本:
var projectModel = new ProjectModel(); // assume that ProjectModel is a ref type
projektyModel = SetGrid(projectModel);
bool sameObject = object.ReferenceEquals(projectModel, projektyModel); // true
使用泛型可以更好地实现这一点。您可以对泛型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;
}
这里,泛型typeparam“T”实际上是由编译器通过调用该方法的方式推断出来的
值得注意的是,在您演示的特定用例中,返回
grid
可能是不必要的,由于原始变量引用将在方法调用后进行适当修改。因为您要传入实现IGrid的类的对象,所以您也可以将返回类型更改为IGrid
此外,由于它是引用类型,您甚至不需要再次返回网格。你也可以用这个:
var projectModel = new ProjectModel();
SetGrid(projectModel);
在上述示例中,不需要返回
grid
。IGrid
实例是通过引用传递的,因此您的projectModel
引用将随着您在SetGrid
方法中所做的更改而更新
如果仍要返回参数,请至少返回IGrid
,因为已知该参数是IGrid
一般来说,在使用静态类型语言/方式编程时,请提供尽可能多的类型信息。您的网格是一个IGrid,为什么不返回IGrid?“这是一种常见做法还是应该避免这样做?” 这不是常见的做法。你应该避免这样做
这是一个非常奇怪的例子,因为SetGrid除了设置一些默认值之外似乎没有做很多事情。您还可以让代码在对象上执行操作,该操作本身就可以很好地完成。意思是可以将
IGrid
和ProjectModel
重构为:
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
扩展该抽象类
那么坚实的原则呢?具体而言,是单一责任原则。这门课首先有点像DTO用户137348 我在这里使用的是不可靠的原则,对类的客户机隐藏实现。也就是说,客户端不必访问它正在使用的类的内部,否则就是违反了 (SRP)只告诉类应该只有一个更改的原因,这是一个非常模糊的限制,因为更改可以像您希望的那样窄和宽 我相信,如果参数类足够小的话,可以将一些配置逻辑放在参数类中。否则我会把它全部放在工厂类中。我建议此解决方案的原因是,
IGrid
似乎引用了PagerHelper
和SortHelper
,它们似乎是IGrid
的突变
所以我觉得很奇怪,你提到这个班是一个学生。纯粹意义上的DTO不应该包含除访问器(即getter方法)之外的逻辑,这使得
ProjectModel
本身引用了PagerHelper
和SortHelper
,我认为它们可以对其进行变异(即,它们是setter)。如果您真的想要SRP,“助手”应该在一个工厂类中,该类创建IGrid
/ProjectModel
实例。Highfive用于同时得出相同结论。如果要返回任何内容,为什么不直接返回IGrid呢?如果你把它作为一个扩展方法,我会+1:)那么固体原理呢?具体而言,是单一责任原则。首先,这门课有点像DTO。谢谢你详尽的解释!!提供了一些需要考虑的内容。感谢您的解释,但是这个方法的通用版本呢?
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();