我想知道是否可以动态传递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));
但是我想知道如果没有反思,这是否有可能
答案 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);
}