gpt4 book ai didi

c# - 在通用参数中使用多态性

转载 作者:太空狗 更新时间:2023-10-30 01:33:37 25 4
gpt4 key购买 nike

问题

我有一个扩展方法可以扩展 IEnumerable<T>并取 Expression导航到一个本身必须是 IEnumerable 的属性.

/// <summary>
/// Identify a child collection to search on
/// </summary>
/// <param name="source">source data on which to search</param>
/// <param name="property">Enumerable properties to search.</param>
public static IEnumerable<TSource> Search<TSource, TProperty>(
this IEnumerable<TSource> source,
Expression<Func<TSource, IEnumerable<TProperty>> property)
{
// Do stuff...
}

当子属性定义为 IEnumerable<T> 时,上述方法运行良好可以调用如下:

var result = shops.Search(s => s.ProductEnumerable);

但是如果子属性是ICollection<T>,它目前找不到这个方法。 , IList<T>或任何实现 IEnumerable<T> 的东西

另一个关键点是我希望能够在不显式定义类型的情况下使用该方法。

var result = shops.Search(s => s.ProductList);    
//NOT
var result = shops.Search<Shop, Product>(s => s.ProductList);

我尝试过的

尝试 1

我想我可以创建一个新的泛型 ( TCollection ) 并对 TCollection 的位置施加约束是IEnumerable<TProperty> .

public static IEnumerable<TSource> Search<TSource, TCollection, TProperty>(
this IEnumerable<TSource> source,
Expression<Func<TSource, TCollection>> property)
where TCollection : IEnumerable<TProperty>

这失败了,因为代码不再能够找到该方法。

尝试 2

然后我想到我可以使整个第二个参数成为通用参数并对其施加正确的约束。

public static IEnumerable<TSource> Search<TSource, TCollection, TProperty>(
this IEnumerable<TSource> source,
TCollection property)
where TCollection : Expression<Func<TSource, IEnumerable<TProperty>>

这也因以下错误而失败:

Cannot use sealed class Expression<TDelegate> as type parameter constraint.


有没有办法实现我想要的,或者我是否只需要为实现 IEnumerable 的所有接口(interface)创建重载???

提前感谢您花时间阅读这篇冗长的描述

最佳答案

嗯,不,您显示的代码工作正常。问题一定出在你如何使用那个 IEnumerable<TProperty>在您的搜索方法中 - 请记住,因为它是 Func 中的返回值,它必须是协变的。

实际可编译的代码:

void Main()
{
var enumerable = default(IEnumerable<MyItem>);

Search(enumerable, i => i.MyEnumerable);
Search(enumerable, i => i.MyCollection);
}

public static IEnumerable<TSource> Search<TSource, TProperty>
(
IEnumerable<TSource> source,
Expression<Func<TSource, IEnumerable<TProperty>>> property)
{
return null;
}

public class MyItem
{
public IEnumerable<string> MyEnumerable { get; set; }
public ICollection<string> MyCollection { get; set; }
}

编译运行时没有错误。

关于c# - 在通用参数中使用多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33231636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com