<I> 如何创建一个包含 B 实例的列表,给定 A 的实例(A 派生自 B,B 实现 I)?



请参阅以下示例代码。

public interface I
{
    int ID { get; set; }
}
public class B : I
{
    public int ID { get; set; }
    public string PropB { get; set; }
}
public class A : B
{
    public string PropA { get; set; }
    public IEnumerable<I> GetListOfBase()
    {
        // Attempt #1
        var list1 = new List<I>();
        B b1 = this as B;
        list1.Add(b1);
        // Attempt #2
        var list2 = new List<I>();
        B b2 = (B)this.MemberwiseClone();
        list2.Add(b2);

        return list1;
    }
}
private static void TestGetListOfBase()
{
    var a = new A() { ID = 1, PropA = "aaa", PropB = "bbb" };
    var list = a.GetListOfBase();
}

在我的两次尝试中,列表都包含A的实例。我需要它包含B的实例。

EDIT:我需要一个B列表的原因是,稍后每个B都会被传递到NPoco(一个从PetaPoco派生的.NET微ORM)中。NPoco获取类型的名称,并使用它来确定要映射到的DB表。因此,将正确类型的变量传递给方法至关重要。

不,没有办法将派生类的实例"转换"为基类的实例。您必须创建基类的新实例并复制属性。

有多种方法可以做到这一点,包括手动复制每个属性(适用于少量属性)。这种操作通常被称为"映射"(希望它能帮助您搜索工具)。

请注意,如果您对列表Enumerable.OfType<T>()Enumerable.Cast<T>()后面跟着ToList()的不同类型感到满意,则可以在单个语句中解决此问题。

在给定类型a的实例(或任何可分配给B的实例)的情况下,可以使用copy constructor轻松创建类型B的实例:

public class B : I
{
    public int ID { get; set; }
    public string PropB { get; set; }
    public B(source B)
    {
        // copy values
        this.ID = source.ID;
        this.PropB = source.PropB;
    }
}

你可以这样称呼它:

A instanceOfA = new A();
B instanceOfB = new B(instanceOfA);
// typeof(instanceOfB) == B

最新更新