Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IEnumerable<;T>;未知类型保留类信息_C#_.net_Linq - Fatal编程技术网

C# IEnumerable<;T>;未知类型保留类信息

C# IEnumerable<;T>;未知类型保留类信息,c#,.net,linq,C#,.net,Linq,我正在尝试编写一个属性过滤器,它接受一个IEnumerable,并调用skip和take 在OnActionExecuted中,我得到了一个对象,我可以将它强制转换为IEnumerabe,并调用skip and take on(完美),效果很好 问题是skip和take似乎要走了,我被强制转换为IEnumerable,所以我将返回一个IEnumerable,完全删除类型信息 这在大多数情况下都很好,但是我想使用多个属性,让它们检查类型信息,比如说对象名称,第二个操作过滤器中的类型信息已经变成了对

我正在尝试编写一个属性过滤器,它接受一个
IEnumerable
,并调用skip和take

在OnActionExecuted中,我得到了一个对象,我可以将它强制转换为
IEnumerabe
,并调用skip and take on(完美),效果很好

问题是skip和take似乎要走了,我被强制转换为
IEnumerable
,所以我将返回一个
IEnumerable
,完全删除类型信息

这在大多数情况下都很好,但是我想使用多个属性,让它们检查类型信息,比如说对象名称,第二个操作过滤器中的类型信息已经变成了对象

基本上有什么可以拥有的吗

var list = new List<string>{"a","b","c"};

var objectlist = list as IEnumerable<object>;    
var newenumerable = objectlist.Take(10);

newenumerableastype = newenumerable as IEnumerable<string>
Assert.IsNotNull(newenumerableastype); //Currently this will be null as newenuerable is IEnumerable<object>
var list=新列表{“a”、“b”、“c”};
var objectlist=列表为IEnumerable;
var newenumerable=objectlist.Take(10);
newenumerableastype=作为IEnumerable的newenumerable
Assert.IsNotNull(newenumerableastype)//当前该值将为null,因为newenuerable是IEnumerable
似乎没有任何工具可以强制从变量中键入IEnumerable(我可以在LINQ查询之前得到它,但没有强制转换/转换它的能力……这是毫无意义的)

编辑:

我将尝试让它更清晰一点,我尝试插入WebAPI2 actionfilters,这些基本上给了我一个“对象”,它是控制器上的返回类型。我可以使用反射来确定它是一个IEnumerable,甚至可以通过检查枚举类型来确定类型

问题是没有办法将“对象”视为它的类型,但我不关心实际的类型t,只关心获取它的类型信息

Take和Skip的C#扩展方法似乎创建了一种新的IEnumerable,它是前一种的子集,这就是我想要的,问题是它们在这个过程中删除了类型信息

(IEnumerable<object> variable).Take(10) // returns an IEnumerable<object>
(IEnumerable变量).Take(10)//返回IEnumerable
我非常希望我的方法1)不必预定义类型(将泛型添加到属性会起作用,但不受语言支持),或2)允许扩展方法返回
IEnumerable
,返回的是基于
IEnumerable
的构造内容,而不是它的强制转换形式

更新:

因此,在“使”事物工作的现实世界中,我发现我能够在ActionFilter executedContext上使用不同的属性,这似乎具有原始类型信息(即使我弄乱了IEnumerable),因此过滤器“链”中的后续事物可以获得类型信息

尽管如此,这仍然是一个有趣的问题,我还是很好奇,我是否能够以某种方式调用可枚举的take并保留类型信息(撇开它奇怪的take是如何在
IEnumerable
上定义的,它真的应该存在于IEnumerable上吗?take需要知道对象类型是什么吗?它只需要返回其中的X个)

学术上仍然很好奇,在语言中是否有解决这个问题的方法:)

您可以使用
Cast()
方法

var newCollection = newenumerable.Cast<string>()
var newCollection=newenumerable.Cast()
有关更多信息,请参阅msdn:

如果该对象集合上有不同的类型,则可以使用:

var newCollection = newenumerable.OfType<string>()
var newCollection=newenumerable.OfType()

从泛型集合获取类型:

IEnumerable<object> myCollection = new List<string>();
var genericTypeArgument = myCollection.GetType().GetGenericArguments().FirstOrDefault();
IEnumerable myCollection=new List();
var genericTypeArgument=myCollection.GetType().GetGenericArguments().FirstOrDefault();
使用以下方法:

var newenumerable = objectlist.Cast<string>().AsEnumerable();
var newenumerable=objectlist.Cast().AsEnumerable();
似乎没有任何工具可以强制键入 从一个变量中可数

这是正确的,因为IEnumerable的类型是编译时的事情,而变量的类型是运行时的事情。如果您知道IEnumerable中每个对象的所有类型都相同,则可以执行以下操作:

List<string> list = new List<string>{"a","b","c"};

IEnumerable<object> objectlist = list as IEnumerable<object>;    
IEnumerable<object> newenumerable = objectlist.Take(10);


Type listTypeOf = newenumerable.FirstOrDefault().GetType();
Type listType = typeof(List<>).MakeGenericType(listTypeOf);
dynamic dynamicList = Activator.CreateInstance(listType);
foreach (var item in newenumerable)
{
     dynamicList.Add((dynamic) item);
}

IEnumerable<string> newenumerableastype = dynamicList as IEnumerable<string>;

Assert.IsNotNull(newenumerableastype);
List List=新列表{“a”、“b”、“c”};
IEnumerable objectlist=列表为IEnumerable;
IEnumerable newenumerable=objectlist.Take(10);
类型listTypeOf=newenumerable.FirstOrDefault().GetType();
类型listType=typeof(列表)。MakeGenericType(listTypeOf);
DynamicDynamicList=Activator.CreateInstance(listType);
foreach(newenumerable中的var项)
{
dynamicList.Add((动态)项);
}
IEnumerable newEnumerableType=作为IEnumerable的dynamicList;
Assert.IsNotNull(newenumerableastype);
在本例中,这将起作用。在本例中,dynamicList的类型在运行时为
List
。但是,如果对象的初始列表是混合类型的,则会出现一些动态分辨率错误。例如,如果将第一行代码更改为

List<object> list = new List<object>{"one", 2, 3.0};
List List=新列表{“一”,2,3.0};
然后,您将得到一个
RuntimeBinderException
,试图向字符串列表中添加一个整数。这就是你最初的问题存在的原因。如果不知道单个元素的所有类型,则无法将
IEnumerable
安全地强制转换为
IEnumerable


需要明确的是,您可以确定示例中所有内容的类型,只是在编译时不知道这些类型。正如您所确定的,Take会创建一个新的IEnumerable,其类型与源类型相同(这在编译时确定)。关于方差的C#规则试图通过在编译时严格执行来减少运行时错误。您可以使用延迟求值,将特定类型的处理一直保留到LINQ管道的末尾,并逐个类型处理单个元素,但这将是在运行时而不是编译时类型上进行的。

为什么需要使用
object
?这就是ActionFilterAttribute传递的内容。我得到一个HttpActionExecutedContext。我的研究表明,你不能编写具有泛型类型的属性