Use of polymorphism in a general parameter

Problem

I have an extension method that extends IEnumerable<T>and accepts Expression, which goes over to the property that should be 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...
}

This works well when the child property is defined as IEnumerable<T>and can be called as follows:

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

however, it currently does not find this method if a child property ICollection<T>, IList<T>or anything that implementsIEnumerable<T>

Another key point is that I want to use a method without explicitly defining types.

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

What i tried

Attempt 1

I thought I could create a new generic ( TCollection) and put a restriction on where TCollectionthere is IEnumerable<TProperty>.

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

This failed because the code could no longer find a way.

Attempt 2

, .

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

:

Expression<TDelegate> .


, , , IEnumerable???

,

+4
1

, , , , . , 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; }
}

.

+3

Source: https://habr.com/ru/post/1612375/


All Articles