1

假设我们有一堂课

class ComplexCls
{
  public int Fld1;
  public string Fld2;
  //could be more fields
}

class Cls
{
  public int SomeField;
}

然后是一些代码

class ComplexClsList: List<ComplexCls>;
ComplexClsList myComplexList;
// fill myComplexList

// same for Cls    
class ClsList : List<Cls>;
ClsList myClsList;

我们想从 myComplexList 填充 myClsList,类似于(伪代码):

foreach Complexitem in myComplexList
{
  Cls ClsItem = new Cls();
  ClsItem.SomeField = ComplexItem.Fld1;
}

执行此操作的代码很简单,将放在 myClsList 中的某个方法中。但是,对于通用的 ComplexCls,我想将其设计得尽可能通用。请注意,在使用此代码时,确切的 ComplexCls 是已知的,只有算法 shd 是通用的。
我知道可以使用(直接)反射来完成,但还有其他解决方案吗?如果问题不够清楚,请告诉我。(可能不是)。[编辑] 基本上,我需要的是:拥有 myClsList,我需要指定一个 DataSource (ComplexClsList) 和一个来自该 DataSource (Fld1) 的字段,用于填充我的 SomeField

4

3 回答 3

4

这只是一个映射,所以使用一些简单的 LINQ:

ClsList myClsList = new ClsList();
myClsList.AddRange(
  myComplexList.Select(Complexitem => new Cls { SomeField = Complexitem.Fld1 })
);
于 2013-10-24T21:50:54.247 回答
2

好的,假设我们在一个类上有一个已知的目标字段,更简单的版本(我已经把它写成一个扩展方法,不需要做

public IEnumerable<Cls> MapField<TSource>(IEnumerable<TSource> sourceList, 
                                          Func<TSource, int> sourceSelector)
{
  return sourceList.Select(x => new Cls {SomeField = sourceSelector(x)});
}

以这种方式调用

IEnumerable<Cls> result = MapField(myComplexList, x => x.Fld1);

旁白:由于您myComplexList的类型ComplexClsList继承自List(实现IEnumerablethis 将起作用。结果不是ClsList您想要的类型,但您可以轻松调用.ToList()结果并提供一个构造函数,ClsList该构造函数采用List<Cls>.


当我们不知道目标字段(或类型)时,更复杂的版本......

public IEnumerable<TResult> MapField<TSource, TResult, TMap>(
    IEnumerable<TSource> sourceList, 
    Func<TSource, TMap> sourceSelector,
    Func<TMap, TResult> resultCreator)
{
    return sourceList.Select(x => resultCreator(sourceSelector(x)));
}

不是那么漂亮的称呼......

IEnumerable<Cls> result = MapField(
    myComplexList,
    source => source.Fld1,
    valueToMap => new Cls() {SomeField = valueToMap});

可能是更好的方法,但目前我还没有想到。

编辑:实际上,您可以将Func最后一个上的两者组合成一个,它需要 aTSource并创建必要的字段并将其映射到TResult,但我真的不确定您通过额外的抽象层获得了什么......

于 2013-10-25T16:33:54.223 回答
0

您可能首先要重新考虑扩展List类。在这种情况下,继承给了你什么?我怀疑在这里你会更好地支持组合而不是继承。一种可能的方法是:

// If you would say that a ComplexCls "is a" Cls, then maybe your inheritance
// relationship belongs here instead.
public class ComplexCls : Cls { 
}

public class ClsList
{
  public IReadOnlyCollection<Cls> Items {get;set;}
}

public class ComplexClsList
{
  public IReadOnlyCollection<ComplexCls> Items {get;set;}
}

然后您可以轻松地创建一个 ClsClist。

ClsList basicList = new ClsList{Items = complexList.Items};

但是您可能想更进一步,质疑为什么存在ClsListandComplexClsList类。为什么不简单地List直接传递 s 。我的意思是,aClsList和“Clses 列表”(List<Cls>)之间有什么区别?

于 2013-10-24T21:53:58.940 回答