gpt4 book ai didi

c# - 传递 TResult 未知的 Func

转载 作者:太空宇宙 更新时间:2023-11-03 20:38:14 25 4
gpt4 key购买 nike

注意:请适本地重新标记和/或重命名


我有课,FooEnumerator ,它包装了一个 Foo并实现 IEnumerable<FooEnumerator> . 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);
}

...
}

我希望能够使用给定的(任意)表达式对树的每个级别进行排序,该表达式在顶层 FooEnumerator 时定义。已创建,并将此表达式传递给每个新枚举的项目以供使用。

我想使用 lambda 定义排序表达式,就像使用 OrderBy 函数一样。事实上,我打算将 lambda 传递给 OrderBy .

OrderBy 的签名是

OrderBy<TSource, TKey>(Func<TSource, TKey> keySelector)

哪里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);
}

在此用例中如何指定 TKey 的类型(隐式或显式)?

我不想对其进行硬编码,因为我希望能够对底层 Foo 的所有属性进行排序.

最佳答案

嗯,你不能创建类型为 Expression<Func<Foo,TKey>> 的成员委托(delegate)变量自 TKey从未指定。但是,您可以创建类型为 Expression<Func<Foo,IComparable>> 的成员这可能足以满足您的目的。您可能需要更改您的 FooEnumerator当然,构造函数也接受这个签名。

编辑:其他人建议参数化您的 FooEnumerator以便它接受 TKey .你当然可以这样做,但你应该意识到出现的问题:

  1. 通过对枚举器进行参数化,您就可以完成任务了。任何想要存储 FooEnumerator<T> 的代码必须具有类型的先验知识 T .但是,您可以实现非通用接口(interface) IFooEnumerator来处理这个问题。
  2. 如果您想在将来支持对多个字段的排序,那么参数化枚举器会产生问题。C# 不支持具有可变数量类型参数的泛型,这限制了需要的泛型的创建多种任意类型。这个问题比较难处理,因为开始创建 FooEnumerator<T> 很尴尬, FooEnumerator<T1,T2> , FooEnumerator<T1,T2,T3...> , 等等。

关于c# - 传递 TResult 未知的 Func<T, TResult>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4189131/

25 4 0