动态传递GroupBy密钥

时间:2018-12-21 05:21:41

标签: c# linq

我想知道是否可以动态传递GroupBy密钥。例如,

public interface ISampleType
{
}

public class SampleType1:ISampleType
{
}

public class SampleType2:ISampleType
{
}

public class AnotherClass
{
    public string Property1{get;set;}
    public int Property2{get;set;}
}

void Main()
{
    var list = new List<AnotherClass>();
    ISampleType sample = new SampleType1();

    var result = list.GroupBy(x=>x.Property1);
}

在上面的示例中,如果ISample的类型为SampleType2,则需要按Property2进行分组,而我可以使用switch进行此操作,但是不幸的是,这不是我的选择,因为ISampleType的实现会随着时间的推移而增加。

我想知道是否可以在ISampleType中引入一个用作分组键的属性。例如,

 Expression<Func<AnotherClass, TKey>> GroupingKey {get;}

在这里,我感到很惊讶,因为当我在SampleType2中实现接口时,我不太清楚如何传递“ AnotherClass.Property”。

更新

if(sample is SampleType1)
var result = list.GroupBy(x=>x.Property1);
else if(sample is SampleType2)
var result = list.GroupBy(x=>x.Property2);

实现此目标的最佳方法是什么(最好尽可能避免使用反射)?

更新02:

我有一个解决方案,当然是使用反射。

public interface ISampleType
{
   string GroupingKey{get;}
}

public class SampleType1:ISampleType
{
    public string GroupingKey => nameof(AnotherClass.Property1);
}

public class SampleType2:ISampleType
{
    public string GroupingKey => nameof(AnotherClass.Property2);
}

然后

var result = list.GroupBy(c => c.GetType().GetProperty(sample.GroupingKey).GetValue(c, null));

但是我想知道如果没有反思,这是否有可能

1 个答案:

答案 0 :(得分:1)

您有问题,不能在非通用接口中使用通用TKey类型。要合并所有类型,您将需要使用object。在某些情况下,这意味着装箱,但它应该可以工作。

public interface ISampleType
{
    Func<AnotherClass, object> GroupingKey { get; }
}

public class SampleType1 : ISampleType
{
    public Func<AnotherClass, object> GroupingKey => a => a.Property1;
}

public class SampleType2 : ISampleType
{
    public Func<AnotherClass, object> GroupingKey => a => a.Property2;
}

void Main()
{
    var list = new List<AnotherClass>();
    ISampleType sample = new SampleType1();

    var result = list.GroupBy(sample.GroupingKey);
}