将一个列表的内容复制到另一个不同类型的列表
Copy content of one list to another list of a different type
我无法将 List<TemplateSection>
的内容复制到 List<Section>
。这些定义如下:
List<TemplateSection>
是:
public class TemplateSection
{
public string SectionName { get; set; }
public List<MyTemplateItem> MyTemplateItems { get; set; }
}
public class MyTemplateItem
{
public string ItemName { get; set; }
public string ItemText { get; set; }
}
List<Section>
是:
public class Section
{
public string SectionName { get; set; }
public List<MyItem> MyItems { get; set; }
}
public class MyItem
{
public string ItemName { get; set; }
public string ItemText { get; set; }
public string ItemValue { get; set; }
}
ItemValue
在复制时不需要值,或者它可能只是一个空字符串。
List<TemplateSection>
是一个部分和每个部分中的复选框项目的列表,每个复选框都有一个唯一的名称。 List<Section>
是用户进行更新时从表单中保存的值。
我已经尝试过:List<Section> listSection = listTemplateSection.Cast<Section>().ToList();
但它无法投射。
除了在此处提供定义外,我不知道还能如何描述。请帮忙!
编译器无法猜测如何从TemplateSection
转换为Section
。你必须明确地自己做:
var ans = myTemplateSelections.Select(aTemplate => new Section {
SectionName = aTemplate.SectionName,
MyItems = aTemplate.MyTemplateItems.Select(ti => new MyItem {
ItemName = ti.ItemName,
ItemText = ti.ItemText //,
// ItemValue = ???
}).ToList();
};
根据一些评论,如果您愿意编写自己的转换运算符,可以使用 Cast
。
更改模板 类 以包含转换运算符:
public class TemplateSection {
public string SectionName { get; set; }
public List<MyTemplateItem> MyTemplateItems { get; set; }
public static explicit operator Section(TemplateSection src) {
return new Section {
SectionName = src.SectionName,
MyItems = new List<MyItem>(src.MyTemplateItems.Cast<MyItem>())
};
}
}
public class MyTemplateItem {
public string ItemName { get; set; }
public string ItemText { get; set; }
public static explicit operator MyItem(MyTemplateItem src) {
return new MyItem {
ItemName = src.ItemName,
ItemText = src.ItemText
};
}
}
那么你可以使用Cast
:
var sections = new List<Section>(myTemplateSections.Cast<Section>());
C# 不提供 duck typing, as you expect (it looks the same, so I should be able to cast it). Furthermore, C# allows covariance 仅对接口和委托的限制,这会使您的用例变得复杂。而且 List<T>
也不是协变的(IReadOnlyList
会),因此增加了更多的复杂性。通过继承、协变和接口,您可以这样做:
class Program
{
static void Main(string[] args)
{
var list = new List<MySection>();
list.Add(new MySection()
{
Items = new List<MyItem>()
{
new MyItem() { Name = "One", Text = "Two", Value = "Three" }
}
});
// can access value here: list.First().Items.First().Value
IEnumerable<ISection<TemplateItem>> genericList = list;
foreach (ISection<TemplateItem> genericSection in genericList)
{
// no value here
}
}
}
public interface ISection<out T> where T : TemplateItem
{
string Name { get; }
IEnumerable<T> Items { get; }
}
public class TemplateSection<T> : ISection<T> where T : TemplateItem
{
public string Name { get; set; }
public List<T> Items { get; set; }
IEnumerable<T> ISection<T>.Items => Items;
}
public class TemplateItem
{
public string Name { get; set; }
public string Text { get; set; }
}
public class MySection : TemplateSection<MyItem>
{
}
public class MyItem : TemplateItem
{
public string Value { get; set; }
}
协变 IEnumerable
(定义为 out T
)允许我们将 MySection
分配给 IEnumerable
中的 ISection<T>
。我想,还是会有更优雅的方式。
我无法将 List<TemplateSection>
的内容复制到 List<Section>
。这些定义如下:
List<TemplateSection>
是:
public class TemplateSection
{
public string SectionName { get; set; }
public List<MyTemplateItem> MyTemplateItems { get; set; }
}
public class MyTemplateItem
{
public string ItemName { get; set; }
public string ItemText { get; set; }
}
List<Section>
是:
public class Section
{
public string SectionName { get; set; }
public List<MyItem> MyItems { get; set; }
}
public class MyItem
{
public string ItemName { get; set; }
public string ItemText { get; set; }
public string ItemValue { get; set; }
}
ItemValue
在复制时不需要值,或者它可能只是一个空字符串。
List<TemplateSection>
是一个部分和每个部分中的复选框项目的列表,每个复选框都有一个唯一的名称。 List<Section>
是用户进行更新时从表单中保存的值。
我已经尝试过:List<Section> listSection = listTemplateSection.Cast<Section>().ToList();
但它无法投射。
除了在此处提供定义外,我不知道还能如何描述。请帮忙!
编译器无法猜测如何从TemplateSection
转换为Section
。你必须明确地自己做:
var ans = myTemplateSelections.Select(aTemplate => new Section {
SectionName = aTemplate.SectionName,
MyItems = aTemplate.MyTemplateItems.Select(ti => new MyItem {
ItemName = ti.ItemName,
ItemText = ti.ItemText //,
// ItemValue = ???
}).ToList();
};
根据一些评论,如果您愿意编写自己的转换运算符,可以使用 Cast
。
更改模板 类 以包含转换运算符:
public class TemplateSection {
public string SectionName { get; set; }
public List<MyTemplateItem> MyTemplateItems { get; set; }
public static explicit operator Section(TemplateSection src) {
return new Section {
SectionName = src.SectionName,
MyItems = new List<MyItem>(src.MyTemplateItems.Cast<MyItem>())
};
}
}
public class MyTemplateItem {
public string ItemName { get; set; }
public string ItemText { get; set; }
public static explicit operator MyItem(MyTemplateItem src) {
return new MyItem {
ItemName = src.ItemName,
ItemText = src.ItemText
};
}
}
那么你可以使用Cast
:
var sections = new List<Section>(myTemplateSections.Cast<Section>());
C# 不提供 duck typing, as you expect (it looks the same, so I should be able to cast it). Furthermore, C# allows covariance 仅对接口和委托的限制,这会使您的用例变得复杂。而且 List<T>
也不是协变的(IReadOnlyList
会),因此增加了更多的复杂性。通过继承、协变和接口,您可以这样做:
class Program
{
static void Main(string[] args)
{
var list = new List<MySection>();
list.Add(new MySection()
{
Items = new List<MyItem>()
{
new MyItem() { Name = "One", Text = "Two", Value = "Three" }
}
});
// can access value here: list.First().Items.First().Value
IEnumerable<ISection<TemplateItem>> genericList = list;
foreach (ISection<TemplateItem> genericSection in genericList)
{
// no value here
}
}
}
public interface ISection<out T> where T : TemplateItem
{
string Name { get; }
IEnumerable<T> Items { get; }
}
public class TemplateSection<T> : ISection<T> where T : TemplateItem
{
public string Name { get; set; }
public List<T> Items { get; set; }
IEnumerable<T> ISection<T>.Items => Items;
}
public class TemplateItem
{
public string Name { get; set; }
public string Text { get; set; }
}
public class MySection : TemplateSection<MyItem>
{
}
public class MyItem : TemplateItem
{
public string Value { get; set; }
}
协变 IEnumerable
(定义为 out T
)允许我们将 MySection
分配给 IEnumerable
中的 ISection<T>
。我想,还是会有更优雅的方式。