我有一个由几个类使用的接口,并且所有类的接口实现都是相同的。我会让它成为一个基本的抽象类,但是之后它会阻止派生类继续从其他类继承,这是我需要的。因此,而不是在所有类中重新实现相同的接口,我可以以某种方式在一个位置实现接口,如.h文件,并将.h文件包含在cs文件中,以便类实现接口。我可以在.h文件中的C#中实现一个接口吗?
顺便说一下,接口主要由属性组成,并在委托上进行了更改。
我有一个由几个类使用的接口,并且所有类的接口实现都是相同的。我会让它成为一个基本的抽象类,但是之后它会阻止派生类继续从其他类继承,这是我需要的。因此,而不是在所有类中重新实现相同的接口,我可以以某种方式在一个位置实现接口,如.h文件,并将.h文件包含在cs文件中,以便类实现接口。我可以在.h文件中的C#中实现一个接口吗?
顺便说一下,接口主要由属性组成,并在委托上进行了更改。
我在我的C#有点生疏,所以有一定可能是这样做的C#特异性的方式。但是,从更一般的意义上讲,您可以在自己的标准类文件中提供实现。对于需要实现接口的每个类,您仍然需要声明接口方法 - 但不是将冗长的实现复制并粘贴到每个类中,而是可以对共享的“包含”实现进行单线调用。
(这可能不会是最好的解决办法,而应是一个可行的一个至少可以让你开始。)
我会建议你使用一个结构,而不是一个类,以避免额外的分配。 – chuckj 2012-01-15 04:12:53
编辑:从根本上划线 - 根据评论,这可能不是你想要的。
不幸的是,除了通过一些有问题的技术,包括像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
该op想知道如何写一个mixin,而不是如何使用一般的接口。 – 2012-01-15 04:02:18
啊,这是一个不同的蜡球...编辑... – 2012-01-15 04:02:52
C#不具备的头文件的概念。你不能在C#中轻松做到这一点。如果你实现了一个接口,并且你想在另一个类中有相同的实现,那么另一个类需要从实现类派生。
例子:
public interface IFoo
{
void DoSomething();
}
public class SomeClass : IFoo
{
public void DoSomething()
{
}
}
如果你现在就想拥有SomeOtherClass
具有相同的实现作为SomeClass
那么你需要从SomeClass
获得SomeOtherClass
或重新实现或委托调用DoSomething
到SomeClass
一个实例。另一种选择是使用像DynamicProxy这样的工具,它可以支持mixin样式。
您基本上需要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超过几个lin,它仍然可以节省复制/粘贴代码代码。也可以创建一个tt文件并指定所有派生的部分类的名称并生成multiple files。
我没有时间写一个真正的答案,但接口可以有扩展方法。这可能适合你正在寻找的东西,但这取决于你正在尝试做什么 – 2012-01-15 04:05:06
@ 32bitkid谢谢,我来看看。 – mihajlv 2012-01-15 04:12:05
如果扩展方法在你的情况下不能削减它,请尝试将接口实现分解成一个单独的类,该类将保存对几个类之一的包装对象的引用。根据你想要做什么,你可能能够访问你的包装对象,例如通过'IServiceProvider'。 – 2012-01-15 04:14:48