如何创建包含 B 实例的列表 <I>,给定 A 实例(A 派生自 B,B 实现 I)?
How to create a List<I> containing instances of B, given instances of A (A derives from B and B implements 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 的实例。我试图避免创建新的 B,然后将 A 的属性复制到 B(我认为这会起作用!).
编辑:我需要 B 列表的原因是稍后每个 B 都被传递到 NPoco(一个 .NET 微型 ORM,派生自 PetaPoco)。 NPoco 获取类型的名称并使用它来确定要映射到的 DB table。因此,将正确类型的变量传递给方法至关重要。
不,无法将派生 class 的实例 "convert" 转换为基础 class 的实例。您必须创建基础 class 的新实例并复制属性。
有多种方法可以做到这一点,包括手动复制每个 属性(适用于少量属性)。此操作经常被称为"mapping"(希望对您搜索工具有所帮助)。
请注意,如果您对列表 Enumerable.OfType<T>()
或 Enumerable.Cast<T>()
后跟 ToList()
的不同类型感到满意,则可以在单个语句中解决它。
您可以使用 copy constructor
轻松创建类型 B 的实例,给定类型 A 的实例(或任何可分配给 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
参见下面的示例代码。
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 的实例。我试图避免创建新的 B,然后将 A 的属性复制到 B(我认为这会起作用!).
编辑:我需要 B 列表的原因是稍后每个 B 都被传递到 NPoco(一个 .NET 微型 ORM,派生自 PetaPoco)。 NPoco 获取类型的名称并使用它来确定要映射到的 DB table。因此,将正确类型的变量传递给方法至关重要。
不,无法将派生 class 的实例 "convert" 转换为基础 class 的实例。您必须创建基础 class 的新实例并复制属性。
有多种方法可以做到这一点,包括手动复制每个 属性(适用于少量属性)。此操作经常被称为"mapping"(希望对您搜索工具有所帮助)。
请注意,如果您对列表 Enumerable.OfType<T>()
或 Enumerable.Cast<T>()
后跟 ToList()
的不同类型感到满意,则可以在单个语句中解决它。
您可以使用 copy constructor
轻松创建类型 B 的实例,给定类型 A 的实例(或任何可分配给 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