有一个存储元素树的类。子元素存储在
中public List<BaseTreeData> Child { get; set; }
我想将此树显示为所有元素的“平面”(线性)列表。在将类划分为两个类(基本类和继承类)之后, GetChildren 方法会生成有关类型不匹配的错误。很有可能一切都是合乎逻辑的,但是如何解决呢?
错误CS1503参数1:无法从“ ConsoleApplication1.BaseTreeData”转换为“ ConsoleApplication1.TreeData”
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var data = new List<TreeData>();
for (int i = 0; i < 5; i++)
{
var item = new TreeData() { Name = i.ToString() };
for (int j = 0; j < 3; j++)
{
var number = (i + 1) * 10 + j;
item.Child.Add(new TreeData() { ID = number, Name = number.ToString(), Parent = item });
}
data.Add(item);
}
foreach (var item in data.SelectMany(x => GetChildren(x)))
{
Console.WriteLine(item.ID + " " + item.Name + " " + item.IsChecked);
}
}
static IEnumerable<TreeData> GetChildren(TreeData d)
{
return new[] { d }.Concat(d.Child).SelectMany(x => GetChildren(x));
}
}
class BaseTreeData
{
public bool IsChecked { get; set; }
public BaseTreeData Parent { get; set; }
public List<BaseTreeData> Child { get; set; }
public BaseTreeData()
{
Child = new List<BaseTreeData>();
}
}
class TreeData : BaseTreeData
{
public int ID { get; set; }
public string Name { get; set; }
}
}
答案 0 :(得分:0)
根据您的BaseTreeData
类定义,child
和parent
将始终返回基类型。您可以使用泛型来解决此问题,以使Children
与父类的类型相同:
class BaseTreeData<T> where T : BaseTreeData<T>
{
public bool IsChecked { get; set; }
public T Parent { get; set; }
public List<T> Children { get; set; }
public BaseTreeData()
{
Children = new List<T>();
}
public IEnumerable<T> GetAncestors()
{
if (Parent == null)
yield break;
T relative = Parent;
while (relative != null)
{
yield return relative;
relative = relative.Parent;
}
}
public IEnumerable<T> GetDescendants()
{
var nodes = new Stack<T>();
nodes.Push(this as T);
while (nodes.Any())
{
var current = nodes.Pop();
yield return current;
foreach (var childNode in current.Children)
nodes.Push(childNode);
}
}
}
class TreeData : BaseTreeData<TreeData>
{
public int ID { get; set; }
public string Name { get; set; }
}
答案 1 :(得分:-1)
您的基类属性Child
的类型为List<BaseTreeData>
,但是您正在尝试调用静态方法GetChildren
,该方法需要类型为TreeData
的对象。您实质上是在尝试向上投射对象。编译器将如何知道用什么填充ID
和Name
?
一种更优雅的方法是让每个类决定其字符串表示形式。因为您只可以使用基类的GetChildren
属性,所以无需使用Child
方法:
foreach (var item in data.SelectMany(x => x.Child))
{
Console.WriteLine(item.ToString());
}
然后,您重写ToString
实现,以便基类提供其值,而派生类基于此实现:
class BaseTreeData
{
//Other stuff here
//...
public override string ToString()
{
return IsChecked.ToString();
}
}
class TreeData : BaseTreeData
{
//Other stuff here
//...
public override string ToString()
{
var format = "{0} {1} {2}";
var stringRepresentation = string.Format(format, ID, Name, base.ToString());
return stringRepresentation;
}
}
在参数中注意对base.ToString()
的调用。
输出:
10 10错误
11 11错误