2012-03-27 68 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