0

C#の問題で困っています。

私が取り組んでいるプロジェクトには、consumable情報を格納するクラスがいくつかありconsumer、それらの消費可能なクラスを使用するクラスがあります。

私は次のようなより簡単な方法で物事を複製しました:

using System;
using System.Collections.Generic;

interface IBase
{
    int x {get;}
}

class BaseClass : IBase
{
    public int x {get; set;}
}

interface IDerived : IBase
{
    int y {get;}
}

class DerivedClass : BaseClass, IDerived
{
    public int y {get; set;}
}

interface IConsumer<in T> where T: class, IBase
{
    void Feed(T arg);
}

class BaseConsumer : IConsumer<IBase>
{
    public void Feed(IBase arg)
    {
        Console.WriteLine(arg.x);
    }
}

class DerivedConsumer : IConsumer<IDerived>
{
    public void Feed(IDerived arg)
    {
        Console.WriteLine(arg.y);       
    }
}

public class Program
{
    public static void Main()
    {
        List<IConsumer<IDerived>> consumers = new List<IConsumer<IDerived>>();
        consumers.Add(new BaseConsumer());
        consumers.Add(new DerivedConsumer());

        DerivedClass d = new DerivedClass() { x = 3, y = 5};

        foreach (IConsumer<IDerived> consumer in consumers)
            consumer.Feed(d);
    }
}

これは完全に正常に動作します。ただし、コンストラクター (または別のメソッド) で別のオブジェクトmiddleを受け取り、Feed 呼び出しをオブジェクトにリダイレクトするコンシューマーもいくつか必要です。consumer例えば:

class MiddleConsumer<T> : IConsumer<T> where T : class, IBase
{
    private IConsumer<T> _consumer;
    public MiddleConsumer(IConsumer<T> consumer)
    {
        _consumer = consumer;
    }

    public void Feed(T arg)
    {
        _consumer.Feed(arg);
    }
}

そして、私はそれを次のように使用します:

consumers.Add(new MiddleConsumer<IBase>(new BaseConsumer());
consumers.Add(new MiddleConsumer<IDerived>(new DerivedConsumer());

ただし、 や などの他の具象クラスと一緒に使用しMiddleConsumerます。したがって、パラメーターを明示的に指定する必要はありません。実際の s 型から取得できます。明確にさせてください。私はこのようなものが欲しいです:(これは有効なC#コードではないことに注意してください)ConsumerBaseConsumerDerivedConsumerTConsumer

class MiddleConsumer<IConsumer<T>> : IConsumer<T>
{
    private IConsumer<T> _consumer;
    public MiddleConsumer(IConsumer<T> consumer)
    {
        _consumer = consumer;
    }

    public void Feed(IDerived arg)
    {
        _consumer.Feed(arg);
    }
}

ただし、予想どおり、奇妙なジェネリックパラメーターがあるため、これは機能しません。

基本型がわからない Consumer を使用して MiddleConsumer オブジェクトを作成できるようにしたいと考えています。つまり、これができるようになりたいです:

consumers.Add(new MiddleConsumer<BaseConsumer>(new BaseConsumer());
consumers.Add(new MiddleConsumer<DerivedConsumer>(new DerivedConsumer());

withを使用するときにコンパイラがそれを参照するだけでよいため、withBaseConsumerを使用するたびに -example- の基本型をチェックしたくありません。何十もの異なるクラスが存在する可能性があることに注意してください。MiddleConsumerConsumerMiddleConsumerConsumer

私の質問は次のとおりです: C# コンパイラにジェネリック パラメーターから消費可能な型を推測させる方法はありますか?MiddleConsumer

ご協力ありがとうございました!

4

1 に答える 1