簡體   English   中英

訪問泛型參數的泛型參數?

[英]Accessing the generic parameter of generic parameter?

我在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使用者,它在構造函數(或另一個方法)中使用另一個consumer對象,該對象將Feed調用重定向到這些對象。 例如:

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與其他具體的Consumer類一起使用,例如BaseConsumerDerivedConsumer 因此,我不必顯式指定T參數,它只需從實際的Consumer的類型中獲取即可。 讓我澄清一下。 我想要這樣的東西:(請注意,這不是有效的C#代碼)

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());

我不想每次都與MiddleConsumer一起使用時都要檢查例如BaseConsumer的基本類型,因為當我將ConsumerMiddleConsumer一起使用時,編譯器只能查看它。 注意,可能有數十種不同的Consumer類。

我的問題是: 有沒有辦法讓C#編譯器從其通用參數推斷MiddleConsumer的消耗類型?

謝謝您的幫助!

C#不支持構造函數的類型推斷,但是您可以做的是通過靜態方法將調用委托給構造函數:

public static class MiddleConsumer
{
    public static MiddleConsumer<T> Create<T>( IConsumer<T> consumer ) where T : class, IBase
    {
        return new MiddleConsumer<T>( consumer );
    }
}

現在,您完全不需要指定通用參數:

consumers.Add(MiddleConsumer.Create(new BaseConsumer());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM