C# 使用唯一ID代码返回对象的信息

C# 使用唯一ID代码返回对象的信息,c#,winforms,oop,C#,Winforms,Oop,我想做一个系统,你可以输入一些关于动物的信息,我现在有一只猫和一只狗。然而,我也希望用户能够使用他们独特的芯片来搜索特定的动物。这些动物有三个变量:名字、年龄和芯片。Name是一个字符串,但age和chipid是int 有人能告诉我如何创建一个使用这三个变量的dog/cat对象和一个可以查找它们的系统吗。我目前使用文本框输入所有这些变量。使用按钮搜索也很好,因此用户在文本框中输入芯片ID,当用户单击按钮时,其余信息显示在他们的文本框输入中 编辑: 万岁!我自己解决了这个问题,我必须创建一个小列表

我想做一个系统,你可以输入一些关于动物的信息,我现在有一只猫和一只狗。然而,我也希望用户能够使用他们独特的芯片来搜索特定的动物。这些动物有三个变量:名字、年龄和芯片。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();
}