[英]Copy content of one list to another list of a different type
I am having trouble copying the contents of a List<TemplateSection>
to List<Section>
. 我在将
List<TemplateSection>
的内容复制到List<Section>
时遇到麻烦。 These are defined as below: 这些定义如下:
List<TemplateSection>
is : 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>
is: 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
does not need a value when it is copied or it could just be an empty string. ItemValue
复制时不需要值,也可以只是一个空字符串。
List<TemplateSection>
is a list of sections and checkbox items in each section with a unique name for each checkbox. List<TemplateSection>
是每个节中节和复选框项的列表,每个节具有唯一的名称。 List<Section>
is the values that are saved from the form when the user makes updates. List<Section>
是用户进行更新时从表单保存的值。
I have tried doing: List<Section> listSection = listTemplateSection.Cast<Section>().ToList();
我试过了:
List<Section> listSection = listTemplateSection.Cast<Section>().ToList();
but it fails to cast. 但无法投放。
I don't know how else to describe this other than providing the definitions here. 除了在此处提供定义之外,我不知道该如何描述。 Please help!
请帮忙!
The compiler can't guess how to convert from TemplateSection
to Section
. 编译器无法猜测如何从
TemplateSection
转换为Section
。 You must explicity do it yourself: 您必须自己明确地执行此操作:
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();
};
Per a couple of comments, you can use Cast
if you are willing to write your own conversion operators. 根据一些评论,如果您愿意编写自己的转换运算符,则可以使用
Cast
。
Change your template classes to include the conversion operators: 更改模板类以包括转换运算符:
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
};
}
}
Then you can use Cast
: 然后您可以使用
Cast
:
var sections = new List<Section>(myTemplateSections.Cast<Section>());
C# does not provide duck typing , as you expect (it looks the same, so I should be able to cast it). C#不像您期望的那样提供鸭子类型 (它看起来一样,所以我应该可以转换它)。 Furthermore, C# allows covariance restrictions only on interfaces and delegates, which makes your use case complicated.
此外,C#仅对接口和委托允许协方差限制,这使您的用例变得复杂。 And the
List<T>
is not covariant either ( IReadOnlyList
would be), so more complexity added. 而且
List<T>
也不是协变的( IReadOnlyList
是协变的),因此增加了更多的复杂性。 With inheritance, covariance and an interface you could do this: 使用继承,协方差和接口,您可以执行以下操作:
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; }
}
The covariant IEnumerable
(defined as out T
) allows us to assign a MySection
to a ISection<T>
within the IEnumerable
. 协变
IEnumerable
(定义为out T
)使我们能够分配一个MySection
到ISection<T>
的内IEnumerable
。 I guess, there will be a more elegant way nevertheless. 我想仍然会有一种更优雅的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.