.NET Core Cast для взаимодействия с универсальным параметром типа, который реализует интерфейс - PullRequest
0 голосов
/ 17 октября 2018

В .NET Core C # я пытаюсь что-то вроде этого:

(IInterface<IParameter>)instance

Где экземпляр new Implementation<Parameter>()

И Implementation : IInterface & Parameter : IParameter

Проблема заключается в приведении общего параметра.Когда я предоставляю Parameter вместо IParameter, это работает, но во время компиляции нет никакого способа узнать, какой тип, который реализует IParameter, будет использоваться.Все эти объекты будут созданы с помощью отражения.

Так есть ли способ, которым этот каст работает?Или каким-то другим способом реализовать это, например, без предоставления универсального параметра типа, например, с помощью typeof.

EDIT Благодаря Ziriax

Полностью рабочий пример:

interface IInterface
{
    void Run(TInput input);
}

abstract class AbstractClass<TInput> : IInterface
    where TInput : IParameter
{
    public abstract void Execute(TInput input);

    public void Run(IParameter input)
    {
        Execute((TInput)input);
    }
}

interface IParameter {}

class Implementation : AbstractClass<Parameter>
{
    public void Run(Parameter input)
    {
    }
}

class Parameter : IParameter {}

class Program
{
    static void Main()
    {
        object instance = new Implementation();
        var castInstance = (IInterface) instance;
        castInstance.Run(new Parameter());
    }
}

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Почему бы вам не добавить неуниверсальный интерфейс:

interface IInterface { void Run(IParameter input); }

А затем позвольте вашему универсальному интерфейсу расширить этот неуниверсальный.

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

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

0 голосов
/ 17 октября 2018

Как у вас сейчас, это не может работать.Ваш класс Implementation реализует IInterface<Parameter>, поэтому его метод Run принимает только параметр конкретного типа Parameter, тогда как IInterface<IParameter> требует, чтобы его метод Run принял экземпляр any тип, который реализует IParameter.

Если разрешен тип приведенных вами типов, я мог бы определить другой класс, который реализует IParameter, например:

public class DifferentParameter : IParameter { ... }

А затем выполните:

castInstance.Run(new DifferentParameter());

Но ваш Run метод Implementation не может принять DifferentParameter!

.NET, поэтому не позволяет вам выполнить саму приведение.

Существуют ситуации, в которых разрешен этот тип приведения - если бы вместо этого ваш интерфейс был определен как:

interface IInterface<out TOutput>
    where TOutput : IResult
{
    TOutput Run();
}

Путем задания универсального параметра out, он делает интерфейс ковариантны .Это ограничивает использование параметра типа в результате вызовов методов, но для ковариантных интерфейсов приведение типа вашего допускается .

Вы можете найти множество документации по ковариации и контравариантности в .NET документация .

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