我可以在C#和.h文件中实现接口吗?

我可以在C#和.h文件中实现接口吗?,c#,class,inheritance,interface,abstract,C#,Class,Inheritance,Interface,Abstract,我有一个被几个类使用的接口,所有类的接口实现都是相同的。我会使它成为一个基本的抽象类,但随后它会阻止派生类从另一个类继承,这是我需要的。因此,与其在所有类中重新实现相同的接口,我可以在一个地方实现接口,比如.h文件,并在cs文件中包含.h文件,以便类“实现”接口 顺便说一句,界面主要由属性组成,并在代理上进行了更改。编辑:在行下划掉所有内容-根据注释,这可能不是您想要的 不幸的是,在C#中,除了通过一些有问题的技术,包括编译后工具(如)之外,混音不能作为内置语言功能使用。一些IoC工具也可以使类

我有一个被几个类使用的接口,所有类的接口实现都是相同的。我会使它成为一个基本的抽象类,但随后它会阻止派生类从另一个类继承,这是我需要的。因此,与其在所有类中重新实现相同的接口,我可以在一个地方实现接口,比如.h文件,并在cs文件中包含.h文件,以便类“实现”接口


顺便说一句,界面主要由属性组成,并在代理上进行了更改。

编辑:在行下划掉所有内容-根据注释,这可能不是您想要的

不幸的是,在C#中,除了通过一些有问题的技术,包括编译后工具(如)之外,混音不能作为内置语言功能使用。一些IoC工具也可以使类似mixin的事情发生(请参阅)

就@32比特小子而言,你可以写。它们不是接口,但允许您从类型外部将行为的实现应用于类型。例如,您可以编写:

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前缀的约定

你可能想了解更多关于这方面的信息,例如:

我对我的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样式。

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

IInterface.cs

public interface IInterface
{
    void Foo();
}
接口

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 #>
<#@ 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 #>
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", "DerivedClassA"); #>
<#= codeText #>
<#@ 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文件,指定所有派生的分部类的名称并生成。

op想知道如何编写mixin,而不是通常如何使用接口。我没有时间编写真正的答案,但接口可以有扩展方法。这可能适合你正在寻找的,但这取决于你想做什么do@32bitkid谢谢,我会看一看。如果扩展方法在您的情况下不能解决这个问题,请尝试将接口实现分解成一个单独的类,该类将包含对几个类之一的包装对象的引用。根据您尝试执行的操作,您可能能够提供对包装对象的访问,例如通过
IServiceProvider
。我建议您使用结构而不是类来避免额外的分配。