2011-08-25 55 views
4

下面不是一個好習慣嗎?從共享某些部件的2個接口實現一個類

public interface IMyImmutableData 
{ 
    int Data { get;} 
} 

public interface IMyMutableData 
{ 
    int Data { set;get;}//implements both get and set 
} 

public class MyData : IMyImmutableData, IMyMutableData 
{ 
    public int Data{get;set;} //implements both IMyImmutableData, IMyMutableData 
} 

void Main() 
{ 
    MyData myData = new MyData{Data=10}; 
    Console.WriteLine(myData.Data); 
} 

的原因,我問的是,ReSharper的給了我以下警告:

我想上面這樣做的原因是,當我創建方法,其使用了「可能的不確定性通過這個接口訪問,而」 MyData類,我想將它作爲IMyMutable或IMyImmutable對象發送,以便該方法的用戶知道他們可以期望該方法更新或不更新傳入的對象。

+3

就像一個筆記,我認爲'IMyReadOnlyData'會比'IMyImmutableData'承載更好的含義,因爲對象是可變的。 –

回答

2

我認爲在這種情況下你的結構很好。您不希望通過單獨的屬性明確實現接口,因爲通過不可變接口訪問的Data實際上會與可變接口的不同。此外,您的實際代碼可能更復雜,因爲在這種情況下,沒有歧義:您通過對象本身訪問Data,因此不需要考慮接口。

一種解決方案具有顯式接口實現是使用一個共同的支持字段,而不是自動性質:

private int _data; 
public int IMyImmutableData.Data 
{ 
    get 
    { 
     return this._data; 
    } 
} 

public int IMyMutableData.Data 
{ 
    get 
    { 
     return this._data; 
    } 
    set 
    { 
     this._data = value; 
    } 
} 
+1

我把這個答案標記爲「答案」,因爲它對我的答案很貼切。但我想,我會用Joel B Fant的解決方案,因爲它更優雅。 –

3

你需要做的實現明確的一個或兩個:

public int IMyImmutableData.Data { get; } 
public int IMyMutableData.Data { get; set; } 

當你標記一個顯式的,它只能在專投作爲類型訪問:

MyData obj = new MyData(); 
obj.Data; // Doesnt exist 
(obj as IMyImmutableData).Data // Exists, specifically cast as this interface 

如果您選擇不將其標記爲明確的,則將其作爲其他適當類型投射時所選擇的屬性。

+0

只是一個註釋 - 顯式實現不能被標記爲public,儘管它們可以通過接口公開訪問,按照Jon Skeet的答案在這裏:http://stackoverflow.com/questions/1392252/c-sharp-what-是明確實施的接口成員的原因是 –

3

我認爲你可以忽略ReSharper的警告,因爲不確定性是故意的。

但是,通常使用包裝類來提供對某些東西的只讀訪問,這樣它就不能被轉換爲任何提供更多功能的東西。

public class MyReadonlyData : IMyReadonlyData { 
    private MyData instance; 

    public int Data { 
     get { 
      return instance.Data; 
     } 
    } 

    public MyReadonlyData(MyData mydata) { 
     instance = mydata; 
    } 
} 
// no access to original object or setters, period. 
+0

我很喜歡這個想法 –

+0

雖然我接受了dlev的回答,但我喜歡你的解決方案,並且將會改造我的項目以使用你的想法。它更優雅(imo)。 –

0

你可以轉換的變量和確切說出你的意思是編譯器:(解決歧義)

MyData myData = new MyData{Data=10}; 
Console.WriteLine(((IMyMutableData)(myData)).Data); 
0

你需要一個組合接口與讀寫接口上的「新」預選賽避免發出尖銳的聲音。此外,您的界面名稱很差。更好的名字就像「IReadableData」和「IWritableData」和「IReadWriteData」。請注意,雖然「IReadableData」沒有提供任何變更數據的方法,但不要過分強調數據意味着數據是不可變的。如果某件事是不變的,它不會被任何人改變;這顯然不是MyData類型的對象的情況。

相關問題