通用的C#属性类型

4
我有三个类,其中两个继承自一个基类,第三个类根据应用程序的状态,我希望引用另外两个类中的一个。
public class Batch
{        
    public Batch() { }
}

public class RequestBatch : Batch
{
    public RequestBatch(string batchJobType) : base(batchJobType) { }

    public override int RecordCount
    {
        get { return Lines.Count; }
    }
}

public class ResponseBatch : Batch
{       
    public ResponseBatch(string batchJobType) : base(batchJobType) { }

    public ResponseBatch(int BatchJobRunID)
    { }
}

有时我需要实例化Child1,有时需要Child2。然而,我有一个模型想要在应用程序中传递以保持一切在一个地方,但我希望使持有Child1和Child2的属性通用化,例如:
public class BatchJob {
   public List<Batch> Batches { get; set; }
}

然后稍后这样做

public List<RequestBatch> GetBatches(...) {}

var BatchJob = new BatchJob();
BatchJob.Batches = GetBatches(...);

然而,编译器告诉我它无法隐式将 Child1 转换为(其基类型)Parent。

在“= GetBatches(...”下出现红色下划线,表示“无法隐式转换类型 'System.Collections.Generic.List' 为 'System.Collections.Generic.List'”

有没有一种方法可以使属性通用化,以便它可以接受任何抽象类型的 Parent?

谢谢!


10
可以,这应该能够起作用。你能展示真正的代码吗? - Yacoub Massad
6
不应该发生这种情况;类可以隐式地转换为它们的基类型。请提供一个完整的示例。例如:class BaseClass { public void MethodA() { Console.WriteLine("BaseClass"); } } class DerivedClass : BaseClass { public void MethodB() { Console.WriteLine("DerivedClass"); } } // 隐式地将DerivedClass实例转换为BaseClass实例 DerivedClass derived = new DerivedClass(); BaseClass baseClass = derived; // 调用基类方法 baseClass.MethodA(); // Output: "BaseClass" // 无法调用派生类方法 // baseClass.MethodB(); // 编译错误!在上面的示例中,DerivedClassBaseClass 的子类,并且可以隐式地转换为 BaseClass 类型。虽然转换后的实例仍然是 DerivedClass 类型,但只能访问 BaseClass 定义的成员。因此,对于 baseClass 实例,只能调用 MethodA 而不能调用 MethodB - SLaks
6
请提供一个完整的最小的示例,并且说明错误信息。这样的问题基本上是“出现了故障”——我们不知道出了什么问题。 - Eric Lippert
3
为什么人们一直点赞这个问题? - Eldar Dordzhiev
2
@EldarDordzhiev 因为这是他的第一个问题,而且描述得相当不错,即使代码不完整。我点赞是因为我厌倦了整天看到质量很差的问题被发布。 - Arian Motamedi
显示剩余11条评论
2个回答

1
你展示的代码片段是有效的。没有编译错误:
class Program
{
    static void Main()
    {
        var rj = new RunningJob();
        rj.Property = new Child1();
        rj.Property = new Child2();
    }
}
public class RunningJob { 
    public Parent Property { get; set; }
}
public class Parent {    }
public class Child1 : Parent {    }
public class Child2 : Parent {    }

这段代码唯一的问题在于,Property 的类型是 Parent,因此无法调用特定于 Child1/Child2 的方法。可以通过在类 RunningJob 的泛型类型参数上添加约束来解决这个问题:
public class RunningJob<TParent> where TParent : Parent
{
    public TParent Property { get; set; }
}

因此,现在确保 Property 是类型为 Parent 或任何派生类型。

0

一个选项...

public new IEnumerable<RequestBatch> GetBatches(...) {
    get 
    {
        return base.GetBatches(...).OfType<RequestBatch>();
    }
}

另外...

如果您不需要修改集合,则只需从List<T>更改为IEnumerable<T>

更多信息...


1
@OP:如果 base.GetBatches 包含除 RequestBatch 实例以外的任何内容都被视为错误,您可能希望将 OfType 替换为 Cast,以便可以检测到此类错误。 - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接