Passing a generic as generic type parameter in c#

帅比萌擦擦* 提交于 2021-02-04 18:49:09

问题


I did a little experiment on generics in C# and I had a problem where I want to pass a generic type as a type parameter with a constraint to implement a generic interface whose type I don't know.

Here is my example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        interface IGenericCollection<T>
        {
            IEnumerable<T> Items { get; set; }
        }

        abstract class GenericCollection<T> : IGenericCollection<T>
        {
            public IEnumerable<T> Items { get; set; }
        }

        //This class holds a generic collection but i have to ensure this class
        //implements my IGenericCollection interface. The problem here is that
        //i dont know which type TGenericCollection is using and so i am unable to
        //pass this information to the constraint. 

        class CollectionOwner<TGenericCollection>
           where TGenericCollection : IGenericCollection< dont know ... >
        {
            protected TGenericCollection theCollection = default(TGenericCollection);
        }

        static void Main(string[] args)
        {
        }
    }
}

I have read several posts here, and all told me its impossible due to limitations of C# and CLR. But what would be the right way to do this?


回答1:


Perhaps you should another type parameter:

class CollectionOwner<TGenericCollection, T2>
   where TGenericCollection : IGenericCollection<T2>
   where T2 : class
{
    protected TGenericCollection theCollection = default(TGenericCollection);
}

Will this suit you need?




回答2:


I don't think there's a problem here, just add another generic parameter to your Owner class:

 class CollectionOwner<T,TGenericCollection>
           where TGenericCollection : IGenericCollection<T>
        {
            protected TGenericCollection theCollection = default(TGenericCollection);
        }



回答3:


You can add the second generic parameter to the implementation class. The static Example method below shows an example of this.

public interface ITest<T>
{
    T GetValue();
}

public class Test<T, U> where T : ITest<U>
{
    public U GetValue(T input)
    {
        return input.GetValue();
    }
}

public class Impl : ITest<string>
{
    public string GetValue()
    {
        return "yay!";
    }

    public static void Example()
    {
        Test<Impl, string> val = new Test<Impl,string>();
        string result = val.GetValue(new Impl());
    }
}



回答4:


Using a second generic parameter is an option 4 sure which i already wanted to use but what about this

    abstract class GenericCollection<T> : IGenericCollection<T>
    {
        public IEnumerable<T> Items { get; set; }
    }

    class ConcreteCollection : GenericCollection<string>
    {

    }

    static void Main(string[] args)
    {
       // will constraint fail here ?
       CollectionOwner<int,ConcreteCollection> o = new  CollectionOwner(int, ConcreteCollection);
    }


来源:https://stackoverflow.com/questions/15301197/passing-a-generic-as-generic-type-parameter-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!