Skip to main content
 首页 » 编程设计

C# 自定义类集合的问题

2024年02月03日2952php

在我的应用程序中,我有机器人,用户可以让机器人执行任意数量的不同任务。每个任务都是派生自抽象类任务的类:

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; } 
} 

这允许子类设置描述,但只能从外部获取它。