选择接受基类或子类作为参数的重载方法

时间:2016-08-05 13:26:48

标签: c# .net inheritance overloading

标题写得很糟糕,因为我真的不知道如何描述我的问题。 我的问题描述如下。 我有两个班:

class BaseModel {
   public string Name {get; set;}
}
class ChildModel : BaseModel {
   public string ChildName {get; set;}
}

我保留上述类实例的第三个类:

class OverallModel {
   public IEnumerable<BaseModel> Models {get; set;}
}

现在我有两种方法:

public MappedBaseModel MapModel(BaseModel source){
    var result = new MappedBaseModel();
    // do magic for basemodel
}
public MappedBaseModel MapModel(ChildModel source){
    var result = new MappedChildModel(); // MappedChildModel is a child of MappedBaseModel
    // do magic for childmodel
}

现在当我迭代Models时:

var list = new List<MappedBaseModel>();
foreach(var model in overallModel.Models){
    list.Add(MapModel(model));
}

我感到困惑,因为代码只调用MapModel(BaseModel),而不调用MapModel(ChildModel)。我做了一个解决方法,检查模型是否为ChildModel类型:

foreach ...
    if(model is ChildModel)
        list.Add(MapModel(model as ChildModel)); // thats just ugly..
    else
        list.Add(MapModel(model));

我的问题是它看起来很糟糕。我不想检查模型的类型只是为了调用其他重载方法。 你能帮我把它变得更优雅吗? 我知道我可能没有提供足够的信息。如果您还需要了解更多信息,请提出问题,我会尝试更深入地解释。 还有,对不起我的英文! 祝你有愉快的一天。

3 个答案:

答案 0 :(得分:1)

这些问题通常使用multiple dispatch来解决,但在您的方案中可能会有些过分。考虑向您的Map()类添加一个虚拟BaseModel方法:

class BaseModel {
    public virtual MappedModelBase Map() {
        var result = new MappedBaseModel();
        // ...
        return result;
    }
}

class ChildModel : BaseModel {
    public override MappedModelBase Map() {
        var result = new MappedChildModel();
        // ...
        return result;
    }
}

然后只是:

var list = new List<MappedBaseModel>();
foreach(var model in overallModel.Models)
    list.Add(model.Map());

现在,如果您进入&#34; enterprisey&#34;东西,这里是如何做这种双重调度风格:

public class Mapper
{
    public MappedBaseModel MapModel(BaseModel source);
    public MappedBaseModel MapModel(ChildModel source);
}

class BaseModel 
{
    public virtual MappedBaseModel MapWith(Mapper mapper)
    {
        return mapper.MapModel(this);
    }
}

class ChildModel : BaseModel 
{
    public override MappedBaseModel MapWith(Mapper mapper)
    {
        return mapper.MapModel(this);
    }
}

var mapper = new Mapper();
foreach(var model in overallModel.Models)
    list.Add(model.MapWith(mapper));

答案 1 :(得分:1)

方法MapModel(或另一个方法)应该被覆盖,在这种情况下不会重载。

答案 2 :(得分:0)

Anton Gogolev的

Answer应该采用上述场景......

另一种方法是使用dynamic类型。你可以这样做:

list.Add(MapModel((dynamic)model));

它将调用相应的过载。