C# 传递函数<;T、 TResult>;TResult未知的地方
注意:请适当地重新标记和/或重新命名C# 传递函数<;T、 TResult>;TResult未知的地方,c#,generics,lambda,C#,Generics,Lambda,注意:请适当地重新标记和/或重新命名 我有一个类,FooEnumerator,它包装了一个Foo,并实现了IEnumerable。Foos表示树状数据结构,枚举的FooEnumerators是当前节点的子节点 Foo是供应商提供的数据对象FooEnumerator实现一组自定义筛选代码 class FooEnumerator : IEnumerable<FooEnumerator> { public Foo WrappedNode { get; private set; }
我有一个类,
FooEnumerator
,它包装了一个Foo
,并实现了IEnumerable
。Foo
s表示树状数据结构,枚举的FooEnumerator
s是当前节点的子节点
Foo
是供应商提供的数据对象FooEnumerator
实现一组自定义筛选代码
class FooEnumerator : IEnumerable<FooEnumerator>
{
public Foo WrappedNode { get; private set; }
public string Name { get { return WrappedNode.Name; } }
public int Id { get{ return WrappedNode.Id; } }
public DateTime Created { get{ return WrappedNode.Created; } }
public FooEnumerator(Foo wrappedNode)
{
WrappedNode = wrappedNode;
}
public IEnumerator<FooEnumerator> GetEnumerator()
{
foreach (Foo child in this.GetChildren())
if(FilteringLogicInHere(child))
yield return new FooEnumerator(child);
}
...
}
其中,TKey
是给定的Func
的返回类型,但是方法签名中的类型参数,在编译时计算出来
示例用法
var x = GetStartingNode();
var sort = n => n.DateTime;
var enu = new FooEnumerator(x, sort);
var sort2 = n => n.Name;
var enu2 = new FooEnumerator(x, sort2);
然后,排序表达式将存储在类变量中,FooEnumerator
的工作方式如下:
// pseudo-implementation
private Expression<Func<Foo, TKey>> _sortBy;
public FooEnumerator(Foo wrappedNode, Expression<Func<Foo, TKey>> sortBy)
{
WrappedNode = wrappedNode;
_sortBy = sortBy;
}
public IEnumerator<FooEnumerator> GetEnumerator()
{
foreach (Foo child in this.GetChildren().OrderBy(_sortBy))
if(FilteringLogicInHere(child))
yield return new FooEnumerator(child);
}
//伪实现
私密的表达;
公共FooEnumerator(Foo wrappedNode,表达式排序)
{
WrappedNode=WrappedNode;
_sortBy=sortBy;
}
公共IEnumerator GetEnumerator()
{
foreach(this.GetChildren().OrderBy(_sortBy))中的Foo-child
if(过滤器glogicinhere(儿童))
返回新的FooEnumerator(子项);
}
如何在此用例中指定TKey的类型(隐式或显式)?
我不想硬编码,因为我希望能够对底层
Foo
的任何和所有属性进行排序 嗯,您不能创建类型为Expression
的成员委托变量,因为从未指定TKey
。但是,您可以创建一个类型为Expression
的成员,该类型可能满足您的需要。当然,您可能需要更改FooEnumerator
构造函数以接受此签名
编辑:其他人建议参数化FooEnumerator
,以便它接受TKey
。您当然可以这样做,但您应该了解出现的问题:
FooEnumerator
的代码都必须事先知道类型T
。但是,您可以实现一个非通用接口IFooEnumerator
,来处理这个问题FooEnumerator
,FooEnumerator
,FooEnumerator
,等等都很麻烦当然,您不能创建类型为
Expression
的成员委托变量,因为从未指定TKey
。但是,您可以创建一个类型为Expression
的成员,该类型可能满足您的需要。当然,您可能需要更改FooEnumerator
构造函数以接受此签名
编辑:其他人建议参数化FooEnumerator
,以便它接受TKey
。您当然可以这样做,但您应该了解出现的问题:
FooEnumerator
的代码都必须事先知道类型T
。但是,您可以实现一个非通用接口IFooEnumerator
,来处理这个问题FooEnumerator
,FooEnumerator
,FooEnumerator
,等等都很麻烦您还可以参数化枚举数:
class FooEnumerator<TKey> {
// ... All your 'pseudo' code would work here
}
类枚举器{
//…您所有的“伪”代码都可以在这里工作
}
我建议使用
IComparable
对接口进行编程。您也可以参数化枚举器:
class FooEnumerator<TKey> {
// ... All your 'pseudo' code would work here
}
类枚举器{
//…您所有的“伪”代码都可以在这里工作
}
但是,我建议使用IComparable
对接口进行编程