我可以在.h文件中的C#中实现一个接口吗
本文关键字:一个 接口 实现 文件 我可以 | 更新日期: 2023-09-27 18:20:15
我有一个由多个类使用的接口,并且所有类的接口实现都是相同的。我会让它成为一个基本抽象类,但它会阻止派生类稍后从另一个类继承,这是我需要的。因此,与其在所有类中重新实现相同的接口,我可以在一个地方以某种方式实现接口吗,比如一个.h文件,并将.h文件包括在cs文件中,这样类就可以"实现"接口。
顺便说一句,接口主要由属性组成,并在委托时进行了更改。
我对C#有点生疏,所以肯定有一种特定于C#的方法可以做到这一点。但是,从更一般的意义上讲,您可以在它自己的标准类文件中提供实现。对于每个需要实现接口的类,您仍然需要声明接口方法,但您可以对共享的"include"实现进行单行调用,而不是将冗长的实现复制并粘贴到每个类中。
(这可能不是最好的解决方案,但应该是一个可行的方案,至少可以让你开始。)
C#没有头文件的概念。在C#中你不可能轻易做到这一点。如果您实现了一个接口,并且希望在另一个类中具有相同的实现,那么另一个类别需要从实现类别派生。
示例:
public interface IFoo
{
void DoSomething();
}
public class SomeClass : IFoo
{
public void DoSomething()
{
}
}
如果您现在想要具有与SomeClass
具有相同实现的SomeOtherClass
,那么您需要从SomeClass
派生SomeOtherClass
,或者重新实现它,或者将对DoSomething
的调用委托给SomeClass
的实例。另一种选择是使用类似DynamicProxy的工具,它可以支持mixin样式。
EDIT:根据注释,删除行下的所有内容,这可能不是您想要的。
不幸的是,除了通过一些有问题的技术(包括PostSharp等编译后工具)之外,混合插件并不能作为C#中的内置语言功能使用。一些IoC工具也可以使类似mixin的事情发生(请参阅INotifyPropertyChange的最佳实现)。
就@32bitkid而言,您可以编写扩展方法。它们不是接口,但允许您将行为的实现从该类型外部应用到该类型。例如,你可以写:
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; }
}
(顺便说一句,这是一个自动实现属性的例子)
从技术上讲,IFoo甚至不需要在它自己的文件中——它可以在任何.cs文件中。按照惯例,它通常是自己的。另外,请注意接口使用I前缀的约定。
你可能想阅读更多关于这方面的内容,例如:http://www.csharp-station.com/Tutorials/Lesson13.aspx
您基本上需要C#不支持的多重继承,但是您仍然可以在已经从另一个类派生的其他类中使用接口实现。我想到的一种方法是使用分部类和T4文本模板。这是一个轻微的破解,但它比在许多派生类中复制/粘贴相同的接口实现要好。下面是一个简化的例子:
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();
}
}
派生类接口Impl.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文件,指定所有派生的分部类的名称,并生成多个文件。