2010-02-05 65 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

相關問題