Создание универсального интерфейса в C # - PullRequest
3 голосов
/ 15 ноября 2011

Я знаю, что заголовок может вводить в заблуждение (или даже вводить в заблуждение), но я планирую создать универсальный интерфейс, и в нем должен быть реализован метод с использованием универсального параметра.

При реализации в классе AFirst он должен иметь метод MyMethod<A>(), который возвращает тип A, а при реализации в классе BFirst он должен иметь метод MyMethod<B>(), который возвращает тип B. Мне нужно это функциональность, так как между A и B существуют отношения наследования (и многие другие), и мне нужен универсальный метод, который я могу вызвать с любым из базовых классов.

Если это сбивает с толку, взгляните на то, что я хочу сделать:

Рассмотрим, что B происходит от A. Рассмотрим AFirst и BFirst: IMyInterface<A> и IMyInterface<B> соответственно:

BFirst mySecondObj = new BFirst();
A myA = BFirst.MyMethod<A>();
B myB = BFirst.MyMethod<B>();

Мне нужен доступ к шаблонам MyMethod для базовых классов, поэтому, когда я создаю экземпляр экземпляра BFirst, я могу вызвать либо MyMethod для A, либо B. Я строю систему шаблонов и думаю, что AFirst и BFirst являются шаблонами, а MyMethod действует как фабричный метод. У меня будет большая иерархия, и проект должен быть расширяемым, выводя еще больше классов из моего базового класса A, поэтому я не могу просто создать отдельные интерфейсы или методы для каждого из них.

Я пробовал это:

interface IMyInterface<T> where T : A
{
    T GetNewInstance<T>();
}

и я попытался реализовать этот способ, но я получаю его таким, каким он был создан, когда я нажимаю "реализовать":

class AFirst : IMyInterface<A>
{
    public T GetNewInstance<T>()
    {
        throw new NotImplementedException();
    }
}

Не имеет смысла для меня в том смысле, что я указал тип T как A, но он по-прежнему реализуется как T. Например, он пойдет так (ниже я хочу, чтобы бывает)

class AFirst : IMyInterface<A>
{
    public A GetNewInstance<A>()
    {
        throw new NotImplementedException();
    }
}

class BFirst : AFirst, IMyInterface<B>
{
    public B GetNewInstance<B>()
    {
        throw new NotImplementedException();
    }
}

и из внешнего кода, назовите образец как в начале моего вопроса:

BFirst myBFirst = new BFirst();
A a = BFirst.GetNewInstance<A>(); //calls AFirst's method and returns A
B b = BFirst.GetNewInstance<B>(); //calls BFirst's method and returns B

Как это возможно? Спасибо, Может.

Ответы [ 2 ]

9 голосов
/ 15 ноября 2011

В вашем универсальном интерфейсе вы определяете универсальный метод.Я думаю, что это где путаница.Это должен быть обычный метод, который возвращает ваш универсальный тип.Т.е.

interface IMyInterface<T> where T : A
{
    T GetNewInstance();
}

Это будет реализовано как

class AFirst : IMyInterface<A>
{
    public A GetNewInstance()
    {
        throw new NotImplementedException();
    }
}

, что, я думаю, то, что вы хотите.

1 голос
/ 15 ноября 2011

Возможно, вы слишком усложняете это.Вы могли бы рассмотреть Шаблон шаблона .Базовый класс является абстрактным и определяет переопределяемый метод.Классы, наследуемые от этого базового класса, затем предоставляют реализации этого метода.

Вы все еще можете использовать обобщенные элементы и интерфейс, но этот шаблон, вероятно, является основой, с которой вам нужно начинать.Редактировать:

public abstract class ABase<T>
{
    public abstract T MyMethod();
}

public class A : ABase<A>
{
    public override A MyMethod()
    {
        throw new NotImplementedException();
    }
}

public class B : A
{
}

А для реализации интерфейса это будет

public interface IHasMethod<T>
{
    T MyMethod();
}

public abstract class ABase<T> : IHasMethod<T> ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...