Могу ли я реализовать интерфейс в C # в файле .h? - PullRequest
1 голос
/ 15 января 2012

У меня есть интерфейс, который используется несколькими классами, и реализация интерфейса одинакова для всех классов. Я бы сделал его базовым абстрактным классом, но тогда он не давал бы наследующим классам наследовать от другого класса, который мне нужен. Таким образом, вместо того, чтобы переопределить один и тот же интерфейс во всех классах, могу ли я каким-то образом реализовать интерфейс в одном месте, например файл .h, и включить файл .h в файл cs, чтобы класс «реализовал» интерфейс.

Кстати, интерфейс состоит в основном из свойств и изменен для делегатов.

Ответы [ 4 ]

1 голос
/ 15 января 2012

Я немного заржавел на своем C #, поэтому, безусловно, может быть C # -специфичный способ сделать это.Однако в более общем смысле вы можете предоставить реализацию в своем собственном стандартном файле классов.Для каждого класса, который должен реализовать интерфейс, вам все равно нужно объявить методы интерфейса - но вместо того, чтобы копировать и вставлять в каждый из них длинные реализации, вы можете иметь однострочные вызовы к общей реализации «include».

(Возможно, это не лучшее решение, но оно должно быть работоспособным, которое могло бы, по крайней мере, помочь вам начать работу.)

1 голос
/ 15 января 2012

C # не имеет концепции заголовочных файлов.Вы не можете сделать это легко в C #.Если вы реализуете интерфейс и хотите иметь такую ​​же реализацию в другом классе, тогда другой класс должен быть производным от реализующего класса.

Пример:

public interface IFoo
{
    void DoSomething();
}

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

Если вы хотите сейчасимеет SomeOtherClass, которая имеет ту же реализацию, что и SomeClass, тогда вам нужно извлечь SomeOtherClass из SomeClass или переопределить ее или делегировать вызов DoSomething экземпляру SomeClass.Другой вариант - использовать такой инструмент, как DynamicProxy, который поддерживает стили смешивания.

1 голос
/ 15 января 2012

РЕДАКТИРОВАТЬ: поцарапать все ниже строки - в соответствии с комментариями, это, вероятно, не то, что вы хотите.

К сожалению, миксины не доступны как встроенная языковая функция в C #, за исключением некоторых сомнительных методов, включая инструменты для посткомпиляции, такие как PostSharp .Некоторые инструменты IoC могут также приводить к смешанным вещам (см. Лучшая реализация 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

0 голосов
/ 15 января 2012

В основном вам нужно множественное наследование, которое 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();
    }
}

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 и указать имя всех производных частичных классов и сгенерировать несколько файлов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...