我有一个包含不同种类对象的List,有时这些对象有自己的列表。因此,为了获得列表AND子项的OfType<>
(在适用的地方),我创建了一个递归函数。但是,我似乎无法使用List<object>
public static List<T2> OfTypeRecursive<T1, T2>(this List<T1> l) where T2 : Type
{
var retList = l.OfType<T2>().ToList();
foreach (var v in l)
if(v.GetType() == typeof(loopLoopClass))
retList.AddRange(((loopLoopClass)(object)v).loopBody.OfTypeRecursive<T2>());
return retList;
}
我收到此错误
'List<object>' does not contain a definition for 'OfTypeRecursive' and no extension method 'OfTypeRecursive' accepting a first argument of type List<object> could be found (are you missing a directive or assembly reference?)
但是,如果我将this List<T1> l
更改为this List<object> l
,则扩展方法有效。我真的很感激任何帮助。感谢
编辑:我正在使用.net核心
答案 0 :(得分:1)
我不确定我理解你想要什么,但我会尝试一下。
首先,您可以删除第二个通用参数并直接将其替换为Type
,然后您需要为List<object>
而不是List<T>
进行扩展,这样可以保证编译时的安全性
public static List<Type> OfTypeRecursive<T>(this List<object> list)
{
var retList = list.OfType<Type>().ToList();
foreach (var v in list)
if (v.GetType() == typeof(loopLoopClass))
retList.AddRange(((loopLoopClass)v).loopBody.OfTypeRecursive<Type>());
return retList;
}
由于List<object> != List<T>
它不会像你期望的那样工作。 Covariance and contravariance是可以帮助您理解这一点的主题。
答案 1 :(得分:1)
我有一个包含不同类型对象的List,有时这些对象有自己的列表。
需要对此关系进行编码,并且它将驱动您的类型约束方法。
假设您可以控制具体的对象实现,编码可能如下所示:
public interface INestedList
{
List<object> InnerList { get; }
}
public class ContainsNestedList : INestedList
{
public List<object> InnerList { get; }
public string Name { get; }
public ContainsNestedList(string name, List<object> innerList)
{
Name = name;
InnerList = innerList;
}
public override string ToString()
{
return Name;
}
}
注意:Name
的{{1}}属性仅用于视觉识别目的。
如果您无法控制具体的对象类型,那么仍然应该存在某种现有逻辑,这种逻辑会为您提供此ContainsNestedList
- T1
关系,否则就是问题的前提没有坚持。
当您在代码中执行T2
时,因为foreach (var v in l)
是l
,List<T1>
也是v
。此外,检查T1
类型的v
类型是否loopLoopClass
表示T1
是object
(非约束类型)或后代在loopLoopClass
中,后者被转换为where T1 : loopLoopClass
的约束。
鉴于您之后执行loopBody.OfTypeRecursive<T2>()
,并且loopBody
根据评论被称为List<object>
,T1
现已建立为object
这将导致我们沿着以下代码路径前进:
public static class ListExtensions
{
public static List<object> OfTypeRecursive<T>(this List<object> source)
where T : INestedList
{
var itemsToDigInto = source.OfType<T>().ToList();
var output = source.Except(itemsToDigInto.Cast<object>()).ToList();
foreach (T item in itemsToDigInto)
{
Console.WriteLine($"Extracting from InnerList of {item}");
output.AddRange(item.InnerList.OfTypeRecursive<T>());
Console.WriteLine($"Finished processing for {item}");
}
return output;
}
}
public class Program
{
public static void Main()
{
var x = 2;
var y = 4.3m;
var z = "sf";
var p = new ContainsNestedList("p", new List<object> { x, y });
var q = new ContainsNestedList("q", new List<object> { z, p });
var r = new ContainsNestedList("r", new List<object> { x, y, p, q });
var source = new List<object> { x, y, z, q, p, r };
var result = source.OfTypeRecursive<ContainsNestedList>();
result.ForEach(i => Console.WriteLine("{0}", i));
Console.ReadKey();
}
}
编辑:更新以考虑以下前提
你有一个任意对象列表。其中一些对象属于
ClassA
类型。其他一些对象属于其他特定类,比如ClassB
,它被定义为具有对象的内部列表,其中一些对象在类型中也可能是ClassA
或ClassB
。
public static class ListExtensions
{
public static List<T> OfTypeRecursive<T, TU>(this List<object> source)
where TU : INestedList
{
var output = source.OfType<T>().ToList();
var itemsToDigInto = source.OfType<TU>();
foreach (TU item in itemsToDigInto)
{
Console.WriteLine($"Extracting from InnerList of {item}");
output.AddRange(item.InnerList.OfTypeRecursive<T, TU>());
Console.WriteLine($"Finished processing for {item}");
}
return output;
}
}
答案 2 :(得分:0)
请参阅this post上的答案。
以下是定义generic List
的扩展方法的示例:
using System;
using System.Collections.Generic;
namespace ExtensionMethodTester
{
public class Program
{
public static void Main(string[] args)
{
List<string> myList = new List<string>();
myList.MyTestMethod();
}
}
public static class MyExtensions
{
public static void MyTestMethod<T>(this List<T> list)
{
Console.WriteLine("Extension method called");
}
}
}
答案 3 :(得分:0)
问题在于你的定义
public List<object> loopLoopBody
就像错误消息告诉你的那样,对象没有方法
OfTypeRecursive
所以看起来您正在调用列表项上的方法,而不是列表中的方法。 您应该考虑使用T1和T2类型进行投射,而不是&#34; loopLoopClass&#34;和&#34;对象&#34;。也许这可以解决你的问题。