在我的应用程序中,我有机器人,用户可以让机器人执行任意数量的不同任务。每个任务都是派生自抽象类任务的类:
public abstract class Task
{
string description = "default description";
...
}
public class Walk : Task
{
string description = "Do walk";
...
}
public class Talk : Task
{
string description = "Do talk";
...
}
所以每个机器人都有这些任务的集合。集合定义如下:
public class TaskCollection
{
List<Task> _collection = new List<Task>();
public void AddTask(string taskName)
{
_collection.Add( (Task)Activator.CreateInstance(null, taskName).Unwrap() );
}
public int Count()
{
return _collection.Count;
}
public Task GetElement( int i )
{
return _collection[i];
}
}
为了测试它,我创建了一个 TaskCollection 并添加了一些这样的任务:
public TaskCollection tasks = new TaskCollection();
tasks.AddTask( "Walk" );
tasks.AddTask( "Talk" );
然后这段代码显示所有已添加的任务:
for( int i = 0; i < tasks.Count(); i++ )
{
print( tasks.GetElement(i).description );
}
对于每个任务,它打印出“默认描述”而不是在继承类中分配的描述。这是因为我将类实例转换为任务吗?如果我删除该类型转换,我会收到此错误:
“System.Collections.Generic.List.Add(Task)”的最佳重载方法匹配有一些无效参数。
希望它清楚我在这里要做什么。谁能看出我哪里出错了?
最佳答案
您在每个子类中声明了额外的变量,但是您总是打印来自任务的description
变量。子类变量仅隐藏 Task
中的变量。
这里有两个(或更多)选项。
首先,您可以使用多态性:
public abstract class Task
{
public virtual string Description { get { return "default description"; } }
}
public class Walk : Task
{
public virtual string Description { get { return "Do walk"; } }
}
如果在现实中而不是“描述”你真的想要一些在每个具体实现中都会改变的行为,这就很有意义了。
另一种选择是在 Task
中保留单个描述,但将其值传递给构造函数:
public abstract class Task
{
private readonly string description;
protected Task(string description)
{
this.description = description;
}
}
public class Walk : Task
{
public Walk() : base("Do walk")
{
}
}
现在您可以直接从子类中设置该字段,如果您使其可访问,但我强烈建议您将其保密。如果您真的想要“推送”新值,请将其设置为如下属性:
public class Task
{
public string Description { get; protected set; }
}
这允许子类设置描述,但只能从外部获取它。
关于C# 自定义类集合的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5157852/