2012-03-27 100 views
2

我想知道如果我需要公開數據接口但想要在擴展的計算屬性中使用它們,那麼該怎麼走。爲了更清楚:C#:關於接口,實現和繼承的困惑

// The public interface 
public interface IData 
{ 
    int Property { get; } 
} 

// The internal interface 
internal interface IExtendedData : IData 
{ 
    int ExtendedProperty { get; } 
} 

// The assumed implementation of someone using my interface 
public class Data : IData 
{ 
    public Data(int a) 
    { 
     Property = a; 
    } 

    public int Property 
    { 
     get; 
     private set; 
    } 

    public override string ToString() 
    { 
     return Property.ToString(); 
    } 
} 

// My implementation 
internal class ExtendedData : IExtendedData 
{ 
    public ExtendedData(int a) 
    { 
     Property = a; 
    } 

    public int Property 
    { 
     get; 
     private set; 
    } 

    public int ExtendedProperty 
    { 
     get 
     { 
      return 2 * Property; 
     } 
    } 

    public override string ToString() 
    { 
     return Property.ToString() + ExtendedProperty.ToString(); 
    } 
} 

// publicated by me, for the person who uses my dll 
public static class Calculations 
{ 
    public static int DoSomeCalculation(IData data, int parameter) 
    { 
     // This probably don't work, but maybe shows what I want to do 
     IExtendedData tempData = (ExtendedData)data; 
     return tempData.ExtendedProperty * parameter; 
    } 
} 

我真的感到沮喪,因爲我覺得自己缺少一些basical編程技巧。

+0

使用您的dll的人將無法訪問IExtendedData和ExtendData,因爲它們被聲明爲您的程序集/ dll的內部。 – 2012-03-27 08:20:26

+0

如果'Calculations'是在與'IExtendedData'和'ExtendedData'內部相同的程序集中聲明的,那麼這將工作正常。 :) – Richard 2012-03-27 08:25:02

+0

當然。這個人只會自己實現IData接口。在我的例子中,他的實現將是「數據」類。他只會調用靜態的DoSomething方法並傳遞他的「數據」對象。但由於某些複雜性,我需要擴展屬性。我希望這更清楚。 – germanSharper 2012-03-27 08:28:54

回答

3

您可以通過實施ExtendedData作爲實現IData的

internal class ExtendedData : IExtendedData 
{ 

    private IData data; 
    public ExtendedData(IData data) 
    { 
     this.data = data; 
    } 

    public int Property 
    { 
     get { return data.Property; } 
     private set { data.Property = value; } 
    } 

    public int ExtendedProperty 
    { 
     get 
     { 
      return 2 * Property; 
     } 
    }  
} 

一類的包裝解決這個問題,並以此在DoSomeCalculation

IExtendedData tempData = new ExtendedData(data); 
+0

幾乎在看到你的消息之前發佈了相同的答案。它可以完美地解決問題:) – 2012-03-27 08:31:52

+0

我很擔心這個:(......這對我來說很多工作,因爲這些數據接口中有很多很多的屬性,我希望有一個更簡單的方法來映射他們 – germanSharper 2012-03-27 08:42:38

+0

我相信你可以使用繼承自DynamicObject的類作爲通用包裝來避免重新實現IData中的每個屬性,但是你會失去IntelliSense和(很多)運行時性能。 – Jens 2012-03-27 09:00:12

0

ExtendedData可以從數據繼承:

class ExtendedData : Data 
{...} 

並創建一個Data對象添加一個工廠,像這樣:

public class DataFactory 
{ 
    public IData CreateData() 
    { 
     return new ExtendedData(); 
    } 
} 

用戶必須創建所有的數據對象由該工廠。你可以通過Data的構造函數來確保它的內部。
在您的DLL中,您可以投射到ExtendedData

+0

我也已經想過了。但是這會迫使使用我的程序集的人自己寫封裝。假設這個人從數據庫中獲取數據類。如果他只是在這個類中實現接口,他將能夠通過它而不需要進一步的包裝。但顯然,我將不得不採取一種包裝的方式......自己或強迫他,對吧? – germanSharper 2012-03-27 08:52:03