返回未知的通用列表<T>

ste*_*ell 18 c# generics types

并感谢您的帮助.

我如何从一个未知的Generic.List类型的方法返回.

public void Main()
{
  List<A> a= GetData("A");   
}

public List<T> GetData(string listType)
{
   if(listType == "A")
   {
     List<A> a= new List<A>() 
     ...
     return a; 
   }
   else
   {
     List<B> b = new List<B>()
     return b;

   }
}
Run Code Online (Sandbox Code Playgroud)

在下面的示例中,我收到类似于以下内容的错误:无法转换List<A>List<T>

这可能吗?错误发生在'return a;'上 代码行.
另外,我需要做些什么来确保线路上不会发生错误:

List<A> a= GetData("A");   
Run Code Online (Sandbox Code Playgroud)

谢谢,史蒂文

Joh*_*sch 25

IList而不是List<T>.

  • 同意这应该是最终的目标,但它并没有真正帮助他解决眼前的问题. (3认同)

Ant*_*nes 13

限制返回对象列表的替代方法是确保A和B派生自公共基类型或实现公共接口,然后返回该基类型或接口的列表.在Generic方法中包含一个约束: -

List<ICommon> GetData<T>() where T: ICommon
{

}
Run Code Online (Sandbox Code Playgroud)


Ori*_*rds 9

你不能直接返回List<T>这样的.

为什么?基本上是因为List<A>List<B>(或List<string>VS List<int>这是相同的东西)被认为是2完全独立无关的类.
就像你不能string从声明返回的函数返回一个int,你不能从声明返回int列表的函数返回一个字符串List.在<T>这里是一个有点红鲱鱼.你不能写一个返回字符串和整数的泛型方法......

有关此类事情的更多信息,请参见此处.

所以你要做的就是返回两种类型都来自的东西(它们"有共同之处".)
正如John Rasch所说,你可以返回IList,(注意非泛型,所以它只是一个objects 的列表)或者只是返回它作为一个object.遗憾的是,没有办法保留列表的类型.


Kev*_*ler 7

除非有特定原因导致您无法提前指定实际类型,否则您可以将方法本身设为通用:

public void Main() {
    List<A> a = GetData<A>();
}

public List<TType> GetData<TType>() {
     List<TType> list= new List<TType>();
     ...
     return list; 
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*son 5

编辑每个猎户座的答案,加上AnthonyWJones建议的禁令

你可能应该有一个A和B继承的接口/抽象类

    public interface IMyInterface { }
    public class A : IMyInterface { }
    public class B : IMyInterface { }

    public List<IMyInterface> GetData<T>() where T : IMyInterface
    {
        List<IMyInterface> myList = new List<IMyInterface>();
        if (typeof(T) == typeof(A))
        {
            myList.Add(new A());
        }
        if (typeof(T) == typeof(B))
        {
            myList.Add(new B());
        }
        return myList;
    }
Run Code Online (Sandbox Code Playgroud)


Mar*_*man 5

你可以这样做:

public void Main()
{
    List<int> a = GetData<int>();
    List<string> b = GetData<string>();
}

public List<T> GetData<T>()
{
    var type = typeof(T);
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        type = type.GenericTypeArguments[0];
    }

    if (type == typeof(int))
    {
        var a = new List<int> { 1, 2, 3 };
        return a.Select(v => v != null ? (T)Convert.ChangeType(v, type) : default(T)).ToList();
    }
    else if (type == typeof(string))
    {
        var b = new List<string> { "a", "b", "c" };
        return b.Select(v => v != null ? (T)Convert.ChangeType(v, type) : default(T)).ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

也许你可以根据你的需要修改它。