我有一个由几个类使用的接口,并且所有类的接口实现都是相同的。我会把它作为一个基本的抽象类,但是它会阻止派生类稍后从另一个类继承,这是我需要的。因此,不是在所有类中重新实现相同的接口,我可以在某个地方实现接口,如.h文件,并在.cs文件中包含.h文件,以便类“实现”接口。
顺便说一句,界面主要由属性组成,并在委托上更改。
答案 0 :(得分:1)
编辑:根据评论划线以下 - 这可能不是你想要的。
不幸的是,除了通过一些可疑的技术(包括PostSharp之类的后期编译工具)之外,mixins不能作为C#中的内置语言功能使用。一些IoC工具也可以使混合类似的事情发生(参见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();
是的,这就是通常使用接口的方式 - 尽管它们获得.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 :(得分:1)
我的C#上有点生疏,所以肯定会有一种C#特定的方式来做到这一点。但是,从更一般的意义上讲,您可以在自己的标准类文件中提供实现。对于需要实现接口的每个类,您仍然需要声明接口方法 - 但不是将冗长的实现复制并粘贴到每个接口中,您可以对共享的“include”实现进行单行调用。
(这可能不是最好的解决方案,但应该是一个可行的,至少可以让你开始。)
答案 2 :(得分:1)
C#没有头文件的概念。你不能在C#中轻松做到这一点。如果您实现了一个接口,并且希望在另一个类中具有相同的实现,那么另一个类需要从实现类派生。
示例:
public interface IFoo
{
void DoSomething();
}
public class SomeClass : IFoo
{
public void DoSomething()
{
}
}
如果您现在希望SomeOtherClass
具有与SomeClass
相同的实现,那么您需要从SomeOtherClass
派生SomeClass
或重新实现它或将调用委托给{ {1}}到DoSomething
的实例。另一种选择是使用像DynamicProxy这样的工具,它可以支持mixin样式。
答案 3 :(得分:0)
您基本上需要C#不支持的多重继承,但是您仍然可以在已经从另一个类派生的其他类中使用接口实现。我提出的一种方法是使用partial classes和T4 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超过几行代码,它仍然可以保存复制/粘贴代码。也可以只创建一个tt文件并指定所有派生的部分类的名称并生成multiple files。