C# 使用唯一ID代码返回对象的信息
我想做一个系统,你可以输入一些关于动物的信息,我现在有一只猫和一只狗。然而,我也希望用户能够使用他们独特的芯片来搜索特定的动物。这些动物有三个变量:名字、年龄和芯片。Name是一个字符串,但age和chipid是int 有人能告诉我如何创建一个使用这三个变量的dog/cat对象和一个可以查找它们的系统吗。我目前使用文本框输入所有这些变量。使用按钮搜索也很好,因此用户在文本框中输入芯片ID,当用户单击按钮时,其余信息显示在他们的文本框输入中 编辑:C# 使用唯一ID代码返回对象的信息,c#,winforms,oop,C#,Winforms,Oop,我想做一个系统,你可以输入一些关于动物的信息,我现在有一只猫和一只狗。然而,我也希望用户能够使用他们独特的芯片来搜索特定的动物。这些动物有三个变量:名字、年龄和芯片。Name是一个字符串,但age和chipid是int 有人能告诉我如何创建一个使用这三个变量的dog/cat对象和一个可以查找它们的系统吗。我目前使用文本框输入所有这些变量。使用按钮搜索也很好,因此用户在文本框中输入芯片ID,当用户单击按钮时,其余信息显示在他们的文本框输入中 编辑: 万岁!我自己解决了这个问题,我必须创建一个小列表
万岁!我自己解决了这个问题,我必须创建一个小列表来存储我的动物,并创建一个函数来使用它们唯一的ID查看单个动物,但最终成功了。我真的应该再努力一点。谢谢你们的建议!:) 在现代编程中,有一种倾向是将数据(=模型)与显示数据(=视图)的方式分开。如果您想更改查看数据的方式或输入数据的方式,这将使重用数据变得更容易。除了更好的可变性和可重用性之外,这些过程将更小,因此它们将更易于理解和单元测试 要将模型连接到视图,需要一个适配器,通常称为viewmodel。model/view/viewmodel的缩写是MVVM。阅读一些关于这方面的理论 你有一些动物,其中有猫和狗。每种动物都有名字、年龄和芯片。猫和狗可能有更多的功能,它们彼此不同 您确定要保存动物的年龄吗?这意味着您必须定期更新此值。记住像
生日这样的事情不是更好吗
class Animal
{
public int ChipId {get; set;}
public string Name {get; set;}
public DateTime BirthDate {get; set;}
public int Age => (DateTime.Today - this.BirthDay.Date).TotalDays / 365;
}
年龄的计算公式并不完全正确,你必须在闰年和出生日期前后进行调整,但这有点超出了你的问题范围,你明白要点了
public class Cat : Animal
{
...
}
public class Dog : Animal
{
...
}
有人能告诉我如何创建一个使用这三个变量的dog/cat对象和一个可以查找它们的系统吗
我想你知道如何创造一只狗或一只猫。让我们假设您想要制作几个,并且您希望能够搜索它们
你没有告诉我:是所有动物都有独特的芯片,还是猫和狗有相同的芯片?让我们假设它们都使用相同类型的芯片,因此芯片组是唯一的
class AnimalCollection
{
public void Add(Animal animal) {...}
public Animal Find(int chipId) {...}
}
有几个.NET类表示相似项的序列。使用哪种方法取决于您希望对集合执行的操作:添加/删除/项的频率,以及获取特定项的频率
你好像想用芯片来抓动物。如果您需要经常这样做,最有效的方法是创建动物词典。如果你要增加/移除动物远比取走它们(我怀疑),那就考虑使用不同种类的集合。
好的是,因为我创建了一个AnimalCollection
类,我的类(=代码,而不是运算符)的用户不知道我在内部使用哪种方法来存储动物,所以如果以后发现您没有做出正确的决定,您可以随意更改它
class AnimalCollection
{
private IDictionary<int, Animal> animals = new Dictionary<int, Animal>();
public void Add(Animal animal)
{
this.animals.Add(animal.ChipId, animal);
}
public Animal Find(int chipId)
{
if (this.Animals.TryGetValue(chipId, out Animal fetchedAnimal)
{
return fetchedAnimal;
}
else
{
// There is no Animal with this ChipId
return null;
}
}
}
实现取决于您为操作员提供的控制类型。请确保,如果操作员在输入格式中出错,将在此处进行检查。因此,如果数据无效,操作员将收到警告,您永远不会返回无效日期强>
public string ReadName()
{
return this.textBoxName.Text;
}
如果您还想写姓名,请考虑:
public string DisplayedName
{
get => this.textBoxName.Text;
set => this.textBoxName.Text = value;
}
你也可以对生日做同样的事情。另一种方法是使用VisualStudioDesigner添加DateTimePicker控件。使用visual studio属性设置显示格式
public DateTime DisplayedBirthDate
{
get => this.dateTimePickerBirthDate.Value;
set => this.dateTimePicker.BirthDate.Value = value;
}
当然,您可以使用文本框进行此操作,但在这种情况下,您必须检查输入是否正确:
public DateTime GetBirthDate()
{
string birthDateText = this.textBoxBirthDate.Text;
if (DateTime.TryParse(birthDateText, out DateTime birthDate)
{
// input correct:
return birthDate;
}
else
{
// incorrect input
// TODO: decide how to warn the operator: MessageBox?
return DateTime.MaxValue; // so the caller knows that this is an incorrect Date
}
}
对于CHIPID,考虑使用NULTILUPUT控件,因此您知道输入总是INT。当然,您将其隐藏在属性中:
int DisplayedChipId
{
get => ...
set => ...
}
如果您知道无效芯片,如负数或零,请在此处处理
我差点忘了:使用组合框来告诉必须添加哪种动物。使用可视化设计器给它一个值:“猫”、“狗”
操作员填写字段并按下添加按钮。使用visual studio designer添加事件处理程序:
void OnButtonAdd_Clicked(object sender, ...)
{
this.AddAnimal();
}
您还希望按Id查找动物,因此需要输入项来键入请求的动物Id:
int RequestedAnimalId => this.numericUpdownRequestedAnimalId.Value;
视图模型
这是显示的项目和模型之间的粘合剂
Animal CreateAnimalFromDisplay()
{
switch (this.SelectedAnimalType) // Read the combo box with the animal type
{
case Cat:
return new Cat
{
ChipId = this.DisplayedChipId,
Name = this.DisplayedName,
...
};
case Dog:
return new Dog
{
ChipId = this.DisplayedChipId,
Name = this.DisplayedName,
...
};
...
}
}
private void AddAnimal()
{
Animal createdAnimal = this.CreatAnimal();
this.AnimalCollection.Add(Animal);
}
要找到动物:
private Animal GetRequestedAnimal()
{
return this.AnimalCollection(this.RequestedAnimalId);
}
private void DisplayFoundAnimal(Animal foundAnimal)
{
... // fill textBoxes, etc
}
private void DisplayRequestedAnimal()
{
Animal foundAnimal = this.GetRequestedAnimal();
if (foundAnimal != null)
{
this.DisplayFoundAnimal(foundAnimal);
}
else
{
// Animal not found. TODO: decide how to react
}
}
private void OnButtonFind_Clicked(object sender, ...)
{
this.DisplayRequestedAnimal();
}
你看到了吗,因为我把模型和视图分开了,所以大多数方法只有几行。很容易看出每个方法的作用,也很容易对模型方法进行单元测试。如果要更改视图中的某些内容,更改是最小的,类似地,如果要更改模型,大多数视图元素都不必更改。听起来像猫和狗应该从具有这三个公共属性的ChippedAnimal派生出来。我建议不要储存年龄;而是存储生日,以便计算年龄。这个家庭作业一完成年龄就过时了?“一个可以查找它们的系统”-如果您在数据结构中有它们,那么您已经有了这样一个系统。当然,除此之外,你还可以将它们保存在数据库中。当你解决了问题后,如果你愿意,你可以发布并接受自己的答案。这实现了几件事——它将答案标记在仪表板上,以便其他人知道,随着时间的推移,它可能会增加你自己的声誉/徽章,并且(可能是玩世不恭的)它还会告诉你的同学答案(因此可能在作业到期后张贴):D
Animal CreateAnimalFromDisplay()
{
switch (this.SelectedAnimalType) // Read the combo box with the animal type
{
case Cat:
return new Cat
{
ChipId = this.DisplayedChipId,
Name = this.DisplayedName,
...
};
case Dog:
return new Dog
{
ChipId = this.DisplayedChipId,
Name = this.DisplayedName,
...
};
...
}
}
private void AddAnimal()
{
Animal createdAnimal = this.CreatAnimal();
this.AnimalCollection.Add(Animal);
}
private Animal GetRequestedAnimal()
{
return this.AnimalCollection(this.RequestedAnimalId);
}
private void DisplayFoundAnimal(Animal foundAnimal)
{
... // fill textBoxes, etc
}
private void DisplayRequestedAnimal()
{
Animal foundAnimal = this.GetRequestedAnimal();
if (foundAnimal != null)
{
this.DisplayFoundAnimal(foundAnimal);
}
else
{
// Animal not found. TODO: decide how to react
}
}
private void OnButtonFind_Clicked(object sender, ...)
{
this.DisplayRequestedAnimal();
}