C# 在添加到列表时创建新命名的实例



我有一个这样的基本类:

public class task
{
public string tName;
// Construct
public job(string t)
{
tName = t;
}
}

目前我可以这样做:

public class TASKCLASS
{
private task myTaskName1 = new task("name of task 1");
public Dictionary<string, task> tasks = new Dictionary<string, task>();
// Construct
public TASKCLASS()
{
tasks.Add(myTaskName1.tName, myTaskName1);
}
}

太好了,所以有效!但是我有很多任务要添加到字典中 - 现在我知道我不能像这样直接在.Add部分添加我的tasks

public class TASKCLASS
{
public Dictionary<string, task> tasks = new Dictionary<string, task>();
// Construct
public TASKCLASS()
{
tasks.Add("name of task 1", myTaskName1 = new task("name of task 1"));
}
}

因为即使我尝试在.Add行中创建对象myTaskName1也不存在

但是我想知道是否有任何方法可以构建我的任务类,以便我既可以使用tName创建一个新任务类,又可以将其添加到同一行中的字典中以防止某处的 DRY 错误?

想法:我能否为我的作业字典创建一个新方法,以便.Add函数将仅采用task对象的tName和名称?

编辑:我想我可能只是使用task作为基类,并派生一堆称为我想要的方便名称的类。我可能可以循环浏览对象列表并相当轻松地查看其属性,同时还可以随时按其名称调用每个实例。

您可以创建一个构造函数,该构造函数接受任务类的任务名称。此外,还可以添加一个方法,该方法将新任务添加到类中跟踪任务的字典中。您可以创建从任务列表添加到字典中的第二种方法。

添加基于注释:您可以添加常量,如果存在特殊情况的任务,并且您担心错误键入其名称。

您还可以从 Task 继承并创建具有保留名称的派生任务。但这意味着派生类将仅限于字典中的单个实例。我不确定这是否是你想要的。从基类继承来维护名称对我来说似乎有点过分了。

public class Task
{
//protected task name that can only be set in base or derived classes
protected string name;
//Property to return task name
public string Name { get { return name; } }
public Task() {
}
//Task contructor that requires a name value to be instantiated
public Task(string name)
{
this.name = name;
}
}
public class DerivedTask1 : Task
{
public static const string TASK_NAME = "Derived Task Name 1";
public DerivedTask1() 
{
this.name = TASK_NAME;
}
}
public class TaskTracker
{ 
//Private dictionary to hold tasks
private Dictionary<string, Task> tasks;
public TaskTracker()
{
this.tasks = new Dictionary<string, Task>();
}
public void AddTask(Task task) {
//Adds a task to the dictionary, note that there is no error checking and will fail when task with duplicate name is added
this.tasks.Add(task.Name, task);
}
public void AddTasks(List<Task> newTasks)
{
//Adds all tasks in a list to the backing task dictionary
foreach(Task task in newTasks)
{
AddTask(task);
}
}
public Task GetTask(string taskName)
{
if (this.tasks.ContainsKey(taskName))
{
return this.tasks[taskName];
}
else
{
return null;
}
}
}

将任务添加到集合的代码示例:

const string RESERVED_TASK_NAME_1 = "Reserved Task Name 1";
const string RESERVED_TASK_NAME_2 = "Reserved Task Name 2";
var tracker = new TaskTracker();
tracker.AddTask(new Task("Task 1"));
tracker.AddTask(new Task("Task 2"));
var taskList = new List<Task>();
taskList.Add(new Task(RESERVED_TASK_NAME_1));
taskList.Add(new Task(RESERVED_TASK_NAME_2));
tracker.AddTasks(taskList);
var taskFromLookup = tracker.GetTask(RESERVED_TASK_NAME_1);
tracker.AddTask(new DerivedTask1());
var otherTaskFromLookup = tracker.GetTask(DerivedTask1.TASK_NAME);

IDEA:我可以为我的作业字典创建一个新方法,以便.Add函数将简单地采用task对象的tName和名称吗?

这有几个问题。

赋值语句myTaskName1 = new task("name of task 1")返回一个 void,因此即使可以从封闭的作用域内在封闭作用域中创建变量实例,字典最终也不会有任何Values。这可能不会打扰您,但显然您无法在变量存在之前引用它,这就是您正在尝试做的事情,并增加了尝试在外部范围内创建该变量的耀斑!

如果您只是想从 intellisense 获得一些帮助来管理表示特定类实例的数十个或数百个字段/属性/变量,我认为您的问题是应用程序设计。你试图避免编写意大利面条代码,这是令人钦佩的,但你仍然在思考意大利面条:D

简而言之,如果你有几十个或数百个"任务"变量,那么intellisense不会比使用索引列表或键控字典来管理这些变量更能帮助你。虽然你可以用反射和抽象类做一些有趣的事情,但我不确定这会让你接近你想要的,而且实际上可能会让事情变得更糟!

只是为了提供另一种选择,您可以使用enum来近似,例如:

我的任务.cs:

public enum MyTasks
{
taskName1,
taskName2,
taskName3,
taskName4,
taskName5,
taskName6 // Etc...
}

任务词典.cs

public class TaskDict: Dictionary<MyTasks, Task>

如果您有始终需要的某些默认任务,则只需添加一个构造函数方法来TaskDict

public TaskDict()
{
Add(MyTasks.taskName1, new Task("name of task 1"));
Add(MyTasks.taskName2, new Task("name of task 2"));
Add(MyTasks.taskName3, new Task("name of task 3"));
// etc.
}

如您所见,TaskDict是一个键控于MyTasks枚举的字典,值中Task实例。

任务.cs

public class Task
{
string tName;
public Task(string taskName)
{
tName = taskName;
}
public void PrintName()
{
Console.WriteLine(tName);
}
}

现在在您的跟踪器类中,只需将TaskDict作为属性/字段:

任务跟踪器.cs

public class TaskTracker
{
public TaskDict Tasks = new TaskDict();
public TaskTracker()
{
// You could add tasks here if needed
Tasks.Add(MyTasks.taskName5, new Task("the fifth task"));
// Or remove them:
Tasks.Remove(MyTasks.taskName1);
_run();
}
private void _run()
{
foreach(MyTasks t in Tasks.Keys)
{
Tasks[t].PrintName();
}
}
}

我已经重新抛弃了这一点,实现我真正想要的方法实际上是创建一个包含我需要的所有这些函数的抽象类,然后创建派生的空类,其名称是我想要保留并具有 Intelliansense 访问权限。

因为它们只是派生的,所以如有必要,我可以有额外的功能,特别是我的代码要去的地方......额外的奖金!

我想我只是不习惯把每件事都分解成课堂 - 不确定这是趋向还是意大利面,但让我们看看它是如何实现的......

最新更新