C# 制作不带'的对象;t从IEnumerable继承<&燃气轮机;可通过LINQ查询
我有一个名为C# 制作不带'的对象;t从IEnumerable继承<&燃气轮机;可通过LINQ查询,c#,linq,class,object,collections,C#,Linq,Class,Object,Collections,我有一个名为IDCollection的类,它实际上不是一个基于列表,字典,或类似的IEnumerable类型。虽然它确实有一个索引器,但它基于一个名为innerList的私有字典,因此类的对象本身不是列表,也不通过自己的这个访问器保存键值对或项集合 是否可以在LINQ表达式中查询IDCollection对象?如果是,怎么做? 例如,假设对象名为testIdColl。那样的话 from KeyValuePair<string, ID> k in testIDColl select k;
IDCollection
的类,它实际上不是一个基于列表
,字典
,或类似的IEnumerable
类型。虽然它确实有一个索引器,但它基于一个名为innerList
的私有字典,因此类的对象本身不是列表,也不通过自己的这个访问器保存键值对或项集合
是否可以在LINQ表达式中查询IDCollection
对象?如果是,怎么做?
例如,假设对象名为testIdColl
。那样的话
from KeyValuePair<string, ID> k in testIDColl
select k;
来自TestedColl中的KeyValuePair k
选择k;
等等
还有,IQueryable
界面是否涉及到所有内容?这就是您需要为您的班级做的所有事情:
public class IDCollection : IEnumerable<KeyValuePair<string, ID>>
{
private IDictionary<string, ID> List = new Dictionary<string, ID>();
public IEnumerator<KeyValuePair<string, ID>> GetEnumerator()
{
return List.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
查询必须如下所示:
var query =
from k in testIDColl.AsEnumerable()
where k.Key == "x"
select k;
这就是你需要为你的班级做的一切:
public class IDCollection : IEnumerable<KeyValuePair<string, ID>>
{
private IDictionary<string, ID> List = new Dictionary<string, ID>();
public IEnumerator<KeyValuePair<string, ID>> GetEnumerator()
{
return List.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
查询必须如下所示:
var query =
from k in testIDColl.AsEnumerable()
where k.Key == "x"
select k;
最简单的解决方案是实现IEnumerable
。这只是一种方法,您通常可以将其委托给内部集合的GetEnumerator()
,或者使用轻松实现,以产生返回值
类型的名称(IDCollection
)建议它应该实现IEnumerable
,可能是其他一些集合接口(例如ICollection
,IReadonlyCollection
)
如果出于某种原因您不想使用IEnumerable
,您仍然可以让它工作。首先,您需要了解编译器如何处理查询表达式
LINQ查询表达式首先由编译器转换为一系列方法调用。例如,查询表达式
from KeyValuePair<string, int> item in collection
where item.Key == "abc"
select item.Value;
实例方法也会起作用:
class IDCollection
{
public IDCollection Cast<TResult>()
{
return this;
}
public IDCollection Where(Func<KeyValuePair<string, int>, bool> selector)
{
return this;
}
public IDCollection Select<TResult>(Func<KeyValuePair<string, int>, TResult> selector)
{
return this;
}
}
class-IDCollection
{
公共IDCAST集合()
{
归还这个;
}
公共IDCollection,其中(函数选择器)
{
归还这个;
}
公共IDCollection选择(函数选择器)
{
归还这个;
}
}
最简单的解决方案是实现IEnumerable
。这只是一种方法,您通常可以将其委托给内部集合的GetEnumerator()
,或者使用轻松实现,以产生返回值
类型的名称(IDCollection
)建议它应该实现IEnumerable
,可能是其他一些集合接口(例如ICollection
,IReadonlyCollection
)
如果出于某种原因您不想使用IEnumerable
,您仍然可以让它工作。首先,您需要了解编译器如何处理查询表达式
LINQ查询表达式首先由编译器转换为一系列方法调用。例如,查询表达式
from KeyValuePair<string, int> item in collection
where item.Key == "abc"
select item.Value;
实例方法也会起作用:
class IDCollection
{
public IDCollection Cast<TResult>()
{
return this;
}
public IDCollection Where(Func<KeyValuePair<string, int>, bool> selector)
{
return this;
}
public IDCollection Select<TResult>(Func<KeyValuePair<string, int>, TResult> selector)
{
return this;
}
}
class-IDCollection
{
公共IDCAST集合()
{
归还这个;
}
公共IDCollection,其中(函数选择器)
{
归还这个;
}
公共IDCollection选择(函数选择器)
{
归还这个;
}
}
那么一个同时实现IEnumerable的解决方案对您不好吗?为什么?@SimpleVar我不想给IDCollections
所有内置到IEnumerable
的方法。我想要非常紧密的控制,它能做什么,它有多简单。可以这么说,我想这个小小的复杂问题并没有在早些时候打乱我的思路IQueryable
继承自IEnumerable
,因此我认为您最好的解决方案是在您希望不支持的任何方法中抛出NotSupportedException
,并完全实现IQueryable
接口。实现IEnumerable
或将内部列表作为公共可枚举属性公开。第一种解决方案使查询看起来更自然,第二种解决方案没有为您的接口提供所有可枚举方法。@Jenguinie-实际上只有一种方法可在IEnumerable
上实现。实现这一点有什么错呢?那么一个同时实现IEnumerable的解决方案对您不好吗?为什么?@SimpleVar我不想给IDCollections
所有内置到IEnumerable
的方法。我想要非常紧密的控制,它能做什么,它有多简单。可以这么说,我想这个小小的复杂问题并没有在早些时候打乱我的思路IQueryable
继承自IEnumerable
,因此我认为您最好的解决方案是在您希望不支持的任何方法中抛出NotSupportedException
,并完全实现IQueryable
接口。实现IEnumerable
或将内部列表作为公共可枚举属性公开。第一种解决方案使查询看起来更自然,第二种解决方案没有为您的接口提供所有可枚举方法。@Jenguinie-实际上只有一种方法可在IEnumerable
上实现。实施这个有什么不对?谢谢!这确实澄清了@Enigmativity的答案。如果不使用IEnumerableIt,那么如果您可以为实例编写实现,它将非常有用。现在它还没有编译。@Jenguinie所有的IEnumerable
和一些其他类型的方法(比如IQueryable
,ParallelQuery
)都已经实现了,如果你的类实现了IEnumerable
@Enigmativity,你不需要做任何额外的事情来使用它们。你会得到什么错误?它为我编译。@JakubLortz-抱歉,它编译了,但它没有返回任何东西。如果我有一个包含两个元素的内部列表,并且我执行了一个查询,那么我只会返回一个IDCollection
的实例,而不会返回KeyValuePair
的集合。谢谢!这确实澄清了@Enigmativity的答案。如果不使用IEnumerableIt,那么如果您可以编写实现
class IDCollection
{
}
static class IDCollectionExtensions
{
public static IDCollection Cast<TResult>(this IDCollection source)
{
return source;
}
public static IDCollection Where(this IDCollection source, Func<KeyValuePair<string, int>, bool> selector)
{
return source;
}
public static IDCollection Select<TResult>(this IDCollection source, Func<KeyValuePair<string, int>, TResult> selector)
{
return source;
}
}
class IDCollection
{
public IDCollection Cast<TResult>()
{
return this;
}
public IDCollection Where(Func<KeyValuePair<string, int>, bool> selector)
{
return this;
}
public IDCollection Select<TResult>(Func<KeyValuePair<string, int>, TResult> selector)
{
return this;
}
}