传递母类实例并使用子类参数选择正确的覆盖

时间:2017-05-05 10:21:45

标签: c# oop polymorphism overloading

如果我有一个IRecord接口,那么实现它的RecordARecordB类。 如果另一个类Foo具有以下方法:

public void DoStuff(RecordA param){};
public void DoStuff(RecordB param){};

为什么我不能打电话:

public void CallingMethod(IList<IRecord> recordList)
{
   foreach(var item in recordList)
      DoStuff(item); 
}

2 个答案:

答案 0 :(得分:0)

另一种方法是修改CallingMethod以测试每个项目的类型并在调用DoStuff之前将其强制转换为该类型:

public static void CallingMethod(IList<IRecord> recordList)
{
    foreach (var item in recordList)
    {
        if (item is RecordA)
        {
            DoStuff((RecordA)item);
        }
        elseif (item is RecordB)
        {
            DoStuff((RecordB)item);
        }
    }
}

在使用中,您可能将接口和类定义为:

interface IRecord
{
    List<string> Tracks { get; set; }
}

class RecordA : IRecord
{
    public List<string> Tracks { get; set; }
    public int Speed { get; set; }
}
class RecordB : IRecord
{
    public List<string> Tracks { get; set; }
    public int Size { get; set; }
}

然后你的方法会对这两个类的独特属性做一些事情:

public static void DoStuff(RecordA param)
{
    param.Speed = 78;
}

public static void DoStuff(RecordB param)
{
    param.Size = 12;
}

现在,我们可以创建这两个类的实例,将它们添加到它们的公共接口类型列表中,并将该列表传递给CallingMethod

static void Main()
{
    var ra = new RecordA { Speed = 5 };
    var rb = new RecordB { Size = 10 };

    var recordList = new List<IRecord> { ra, rb };

    Console.WriteLine($"record A Speed before: {ra.Speed}");
    Console.WriteLine($"record B Size before: {rb.Size}");

    CallingMethod(recordList);

    Console.WriteLine($"record A Speed after: {ra.Speed}");
    Console.WriteLine($"record B Size after: {rb.Size}");

    Console.Write("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

我们可以看到输出确实改变了类的独特属性:

enter image description here

答案 1 :(得分:0)

此模式可能会有所帮助

public interface IRecord 
{
}

public class RecordA : IRecord
{    
}

public class RecordB : IRecord
{
}

public class RecordCollection<T> : List<IRecord>  where T : IRecord
{
    public RecordCollection(List<T> records)
    {
    }
}

然后

 public static void CallingMethod(IList<IRecord> recordList)
 {

 }

您可以这样称呼它:

CallingMethod(new RecordCollection<RecordA>(new List<RecordA>()));
CallingMethod(new RecordCollection<RecordB>(new List<RecordB>()));