2012-01-15 44 views
1

我有一个由几个类使用的接口,并且所有类的接口实现都是相同的。我会让它成为一个基本的抽象类,但是之后它会阻止派生类继续从其他类继承,这是我需要的。因此,而不是在所有类中重新实现相同的接口,我可以以某种方式在一个位置实现接口,如.h文件,并将.h文件包含在cs文件中,以便类实现接口。我可以在.h文件中的C#中实现一个接口吗?

顺便说一下,接口主要由属性组成,并在委托上进行了更改。

+3

我没有时间写一个真正的答案,但接口可以有扩展方法。这可能适合你正在寻找的东西,但这取决于你正在尝试做什么 – 2012-01-15 04:05:06

+0

@ 32bitkid谢谢,我来看看。 – mihajlv 2012-01-15 04:12:05

+0

如果扩展方法在你的情况下不能削减它,请尝试将接口实现分解成一个单独的类,该类将保存对几个类之一的包装对象的引用。根据你想要做什么,你可能能够访问你的包装对象,例如通过'IServiceProvider'。 – 2012-01-15 04:14:48

回答

1

我在我的C#有点生疏,所以有一定可能是这样做的C#特异性的方式。但是,从更一般的意义上讲,您可以在自己的标准类文件中提供实现。对于需要实现接口的每个类,您仍然需要声明接口方法 - 但不是将冗长的实现复制并粘贴到每个类中,而是可以对共享的“包含”实现进行单线调用。

(这可能不会是最好的解决办法,而应是一个可行的一个至少可以让你开始。)

+0

我会建议你使用一个结构,而不是一个类,以避免额外的分配。 – chuckj 2012-01-15 04:12:53

1

编辑:从根本上划线 - 根据评论,这可能不是你想要的。

不幸的是,除了通过一些有问题的技术,包括像PostSharp这样的后期编译工具,mixin不能作为C#中的内置语言功能。一些IoC工具也可以使类似mixin的事情发生(请参阅Best implementation of INotifyPropertyChange ever)。

到@ 32bitkid的观点,你可以写extension methods。它们不是接口,但它们允许您将行为的实现应用于该类型之外的类型。例如,你可以写:

public static class IPersonExtensions { 
    // Note use of this keyword 
    public static Int32 GetAge(this IPerson p) { return DateTime.Now - p.BirthDate; } 
} 

然后用它这样的:

var p = new Person(...); 
var pAge = p.GetAge(); 

是的,那是多么的接口通常used-虽然他们得到的.cs文件,而不是.h文件。您可以在它自己的文件中定义接口,就像一个类一样,然后将该类声明为实现接口。

例如,在IFoo.cs:

public interface IFoo { 
    public String Bar { get; set; } 
} 

,然后在ConcreteFoo.cs:

public class ConcreteFoo : IFoo { 
    // This property implements IFoo.Bar 
    public String Bar { get; set; } 
} 

(这是一个auto-implemented property的一个例子的方式)

的IFoo甚至在技术上都不需要在它自己的文件中 - 它可以在任何.cs文件中。按照惯例,它通常是在它自己的。另外,请注意为接口使用I前缀的约定。

你可能想例如阅读更多关于这一点,在这里:http://www.csharp-station.com/Tutorials/Lesson13.aspx

+1

该op想知道如何写一个mixin,而不是如何使用一般的接口。 – 2012-01-15 04:02:18

+0

啊,这是一个不同的蜡球...编辑... – 2012-01-15 04:02:52

1

C#不具备的头文件的概念。你不能在C#中轻松做到这一点。如果你实现了一个接口,并且你想在另一个类中有相同的实现,那么另一个类需要从实现类派生。

例子:

public interface IFoo 
{ 
    void DoSomething(); 
} 

public class SomeClass : IFoo 
{ 
    public void DoSomething() 
    { 
    } 
} 

如果你现在就想拥有SomeOtherClass具有相同的实现作为SomeClass那么你需要从SomeClass获得SomeOtherClass或重新实现或委托调用DoSomethingSomeClass一个实例。另一种选择是使用像DynamicProxy这样的工具,它可以支持mixin样式。

0

您基本上需要C#不支持的多重继承,但是您仍然可以在已经从其他类派生的其他类中使用接口实现。我想出的一种方法是使用partial classesT4 Text Templates。这是一个小小的黑客攻击,但它比在许多派生类中复制/粘贴相同的接口实现要好。下面是一个简化的例子:

IInterface.cs

public interface IInterface 
{ 
    void Foo(); 
} 

InterfaceImpl.cs

public partial class InterfaceImpl : IInterface 
{ 
    public void Foo() 
    { 
     Console.WriteLine("Foo"); 
    } 
} 

BaseClass.cs

using System; 

public class BaseClass 
{ 
    public void Bar() 
    { 
     Console.WriteLine("Bar"); 
    } 
} 

DerivedClassA.cs

public partial class DerivedClassA : BaseClass, IInterface 
{ 
    public void FooBar() 
    { 
     this.Foo(); 
     this.Bar(); 
    } 
} 

DerivedClassAInterfaceImpl.tt

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassA"); #> 
<#= codeText #> 

DerivedClassB.cs

public partial class DerivedClassB : BaseClass, IInterface 
    { 
     public void BarFoo() 
     { 
      this.Bar(); 
      this.Foo(); 
     } 
    } 

DerivedClassBInterfaceImpl.tt

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassB"); #> 
<#= codeText #> 

这是一个有点恼人,这需要创造对于希望每个派生类中的TT文件使用接口实现,但是如果InterfaceImpl.cs超过几个lin,它仍然可以节省复制/粘贴代码代码。也可以创建一个tt文件并指定所有派生的部分类的名称并生成multiple files

相关问题