2

说我有以下代码:

public class Pond
{
  public List<Frog> Frogs { get; set; }
  public List<MudSkipper> MudSkippers { get; set; }
  public List<Eel> Eels { get; set; }
}

public class Frog: IAquaticLife
{

}



public class MudSkipper: IAquaticLife
{

}



public class Eel: IAquaticLife
{

}

现在我想编写一个通用方法,该方法将为某个池塘返回这些类型的列表:

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
   return Uow.GetByID<Pond>(pondId).Eels;
}

好的,所以我在那里的东西将返回那个池塘里的所有鳗鱼。我想做的是归还所有的T。

所以如果我打电话GetByPond<MudSkipper>(1),那将返回所有的弹涂鱼。

有人知道怎么做吗?

4

3 回答 3

5

像这样的东西怎么样

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
   return from t in Uow.GetByID<Pond>(pondId).AquaticLife() 
          where (typeof(t) == typeof(T)) select t;
}

或者简单地说(使用@DStanley 在更改答案之前指出的方法)

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
   return Uow.GetByID<Pond>(pondId).AquaticLife().OfType<T>();
}

这需要Uow.GetByID(int id)返回特定池塘中实现IAquaticLife的所有类型的生物。但是,另一种方法是您将IAquaticLife的各种实现者的知识硬编码到您的通用方法中。这不是一个好主意。

更新

目前,Pond具有EelsMudskippers等单独的集合。如果您想随着代码的发展添加更多实现IAquaticLife的东西,这将变得脆弱,因为您必须同时更改Pond和上面的通用方法。

我建议不要为每种类型的水生生物使用单独的方法,而是使用一个方法来返回池塘中实现IAquaticLife的所有内容,例如

public class Pond
{
    public IEnumerable<IAquaticLife> AquaticLife() { ... }
}

我已经用这个假设更新了我上面的代码。

任何拥有 Pond 实例并想获得例如 Eels 的人都可以这样做:

var eels = pond.AquaticLife().OfType<Eels>();
于 2012-08-28T02:51:29.760 回答
2

试试这个:

return Uow.GetByID<Pond>(pondId).OfType<T>();

编辑

由于您将集合放在单独的属性中,因此您可以使用switch块根据类型返回正确的属性,或者使用反射来根据类型名称获取属性。

根据您的要求,更好的设计是拥有一个List<IAquaticLife>可以存储所有小动物而不是单独属性的私有,但我假设您现在不能这样做。

开关的一个例子是:

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
    switch(typeof(T))
    {
        case typeof(Eel):
            return Uow.GetByID<Pond>(pondId).Eels;
        //etc.
        default:
            throw new ApplicationException(string.Format("No property of type {0} found",typeof(T).Name));
    }
}
于 2012-08-28T02:52:46.393 回答
-1
public Pond GetByPond(int pondId)
{
    return Uow.GetByID<Pond>(pondId);
}

如果您想要 Frogs,请执行以下操作:

var frogs = xxx.GetByPond(1).Frogs;

如果您想要 MudSkippers,请执行以下操作:

var mudSkippers = xxx.GetByPond(1).MudSkippers;

等等。

如果你可以打电话GetByPond<Frog>(1),你可以打电话GetByPond(1).Frogs

如果在任何情况下您都不知道T,则需要创建所有这些的集合并按类型过滤它们。如果您有中间子类型,这也很有用:

public IEnumerable<T> GetByPond<T>(int pondId) where T : IAquaticLife
{
    var pond = Uow.GetByID<Pond>(pondId);
    var life = pond.Frogs.Union(pond.Eels).Union(pond.MudSkippers);
    return life.OfType<T>();
}

但是您连接集合只是为了过滤它们。

于 2012-08-28T04:52:32.953 回答