lexxpavlov
@lexxpavlov
Программист, преподаватель

Как преобразовать generic-объект в не-generic?

using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        var list = new List<IProcessor<INode>>()
        {
            // не удаётся преобразовать из Processor в IProcessor<INode>:
            new Processor(), 
            // InvalidCastException в рантайме:
            (IProcessor<INode>)new Processor(),
            // так тоже не получается:
            new Processor2<Node>(),
        };
        IProcessor<INode> o = new Processor(); // не удаётся неявно преобразовать
    }
}

interface INode { }
interface IProcessor<T> where T : INode { }

class Node : INode { }
class Processor : IProcessor<Node> {}
class Processor2<T> : IProcessor<T> where T : INode { }

Ошибка возникает при преобразовании объекта generic-класса в тип без generic:
IProcessor<INode> o = new Processor(); // не удаётся неявно преобразовать

Проблему со списком можно обойти (например, использовав List), но тогда снова придётся кастить в IProcessor, что невозможно.

Есть ли способы сделать это преобразование?
  • Вопрос задан
  • 769 просмотров
Решения вопроса 1
lexxpavlov
@lexxpavlov Автор вопроса
Программист, преподаватель
В C# нет автоматического преобразования generic-объекта в не-generic. Если такое потребуется, то необходимо сделать это самостоятельно в этом же классе (или в базовом классе). В данном коде преобразование реализовано в классе AbstractProcessor:
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        var list = new List<IProcessor>()
        {
            new Processor(), 
        };
        IProcessor o = new Processor();
        Console.ReadKey();
    }
}

interface INode { }
interface IResult { }

interface IProcessor
{
    INode Get();
    void Print(IResult result);
}
interface IProcessor<out T, in R> : IProcessor where T : class, INode where R : class, IResult
{
    new T Get();
    void Print(R result);
}

abstract class AbstractProcessor<T, R> : IProcessor<T, R> where T : class, INode where R : class, IResult
{
    public abstract T Get();
    public abstract void Print(R result);

    // Преобразование в не-generic тип
    void IProcessor.Print(IResult result)
    {
        Print(result as R);
    }

    INode IProcessor.Get()
    {
        return Get();
    }
}

class Node : INode { }
class Result : IResult { }
class Processor : AbstractProcessor<Node, Result>
{
    public override Node Get() { return null; }
    public override void Print(Result result) {}
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы