c# 方法无法按预期工作地址簿项目
c# Method not working as expected Address book project
我是 c# 的新手,正在处理我的第一个项目 - 一个控制台应用程序。我无法理解为什么当地址簿中的条目已经存在时我的代码不会 return false。以下方法都是 AddressBook 的一部分 class CheckEntry(), AddEntry(), RemoveEntry().
好的,所以布尔方法 CheckEntry() 被其他两种方法使用 - AddEntry() 和 RemoveEntry() - 两者都希望在执行各自的职责之前验证用户条目是否存在。在 AddEntry() 中,应该在添加另一个联系人之前查看联系人是否已经存在,如果存在则不应创建联系人(但它会添加重复项)。 RemoveEntry() 应该检查它是否存在并使用 CheckEntry() 中存储变量的更新值来删除当前联系人(但什么也不做)。
我知道我可能要么遗漏了一些简单的东西,要么对整个过程进行了深思熟虑。我的假设是 checkEntry() 无法正常工作,因为与其相关的两个函数都出现故障。谁有想法??让我知道是否需要进一步解释。
注意:我知道使用列表会更好 efficient/easier。我的目标是将数组用于学习目的。从学习 Javascript 切换到 C# 一直是一个挑战,我想确保我在学习下一件事之前学习了每一件事。
这是我的全部代码。每个 class 由“//--------”分隔 在此先感谢您的帮助。
namespace AddressBook {
class Contact {
public string Name;
public string Address;
public Contact(string name, string address) {
Name = name;
Address = address;
}
}
}
//------------------------------------------------------------------------
using System;
namespace AddressBook {
class AddressBook {
public readonly Contact[] contacts;
public AddressBook() {
contacts = new Contact[2]; ;
}
public void AddEntry(string name, string address) {
Contact AddContact = new Contact(name, address);
if (CheckEntry(name)) {
for (int i = 0; i < contacts.Length; i++) {
if (contacts[i] == null) {
contacts[i] = AddContact;
Console.WriteLine("Address Book updated. {0} has been added!", name);
break;
}
}
}
}
private string existingContact = "";
private bool CheckEntry(string name) {
foreach(Contact contact in contacts) {
if (contact == null) {
break;
}
else if (contact != null && contact.ToString() != name) {
continue;
}
else if (contact.ToString() == name) {
existingContact = contact.ToString();
return false;
}
}
return true;
}
public void RemoveEntry(string name) {
if( !(CheckEntry(name)) ) {
existingContact = null;
Console.WriteLine("{0} removed from contacts", name);
}
}
public string View() {
string contactList = "";
foreach(Contact contact in contacts) {
if(contact == null) {
break;
}
contactList += String.Format("Name: {0} -- Address: {1}" + Environment.NewLine, contact.Name, contact.Address);
}
return contactList;
}
}
}
//------------------------------------------------------------------------
using System;
namespace AddressBook {
class Program {
static void Main(string[] args) {
AddressBook addressBook = new AddressBook();
PromptUser();
void Menu() {
Console.WriteLine("TYPE:");
Console.WriteLine("'Add' to add a contact: ");
Console.WriteLine("'Remove' to select and remove a contact: ");
Console.WriteLine("'Quit' to exit: ");
}
void UpdateAddressBook(string userInput) {
string name = "";
string address = "";
switch ( userInput.ToLower() ) {
case "add":
Console.Write("Enter a name: ");
name = Console.ReadLine();
Console.Write("Enter an address: ");
address = Console.ReadLine();
addressBook.AddEntry(name, address);
break;
case "remove":
Console.Write("Enter a name to remove: ");
name = Console.ReadLine();
addressBook.RemoveEntry(name);
break;
case "view":
Console.WriteLine(addressBook.View());
break;
}
}
void PromptUser() {
Menu();
string userInput = "";
while (userInput != "quit") {
Console.WriteLine("What would you like to do?");
userInput = Console.ReadLine();
UpdateAddressBook(userInput);
}
}
}
}
}
这是我想出的 - 经过测试的更改
现在我不能添加重复的名字,我可以删除条目。
public void AddEntry(string name, string address) {
Contact AddContact = new Contact(); //changed
AddContact.Name = name; //changed
AddContact.Address = address; //changed
if (CheckEntry(name)) {
for(int i = 0; i < contacts.Length; i++) {
if (contacts[i] == null) {
contacts[i] = AddContact;
Console.WriteLine("Address Book updated. {0} has been added!", name);
break;
}
}
}
}
//changed - removed variable and all instances of...
private bool CheckEntry(string name) {
foreach(Contact contact in contacts) {
if (contact == null) {
break;
}
else if (contact != null && contact.Name != name) {
continue;
}
else if (contact.Name == name) {
return false;
}
}
return true;
}
//changed - instead of passing checkentry() as a check I just took care of it here
public void RemoveEntry(string name) {
for(int i = 0; i < contacts.Length; i++) {
if(contacts[i].Name == name) {
contacts[i] = null;
break;
}
}
Console.WriteLine("{0} removed from contacts", name);
}
在 CheckEntry 中,您正在使用字符串类型的参数测试 Contact 类型的对象。这无法工作,因为您正在测试 2 种不同的类型。
如果您覆盖 Contact class 中的 ToString 方法(以便它提供属性 contact.name),它可能会按照您编写的方式工作。
您可以像这样修改您的代码(使用 System.Linq 添加):
private bool CheckEntry(string name)
{
return contacts.Any(a => a.Name == name);
}
首先,我假设您的策略是找到数组中的第一个空槽并在其中插入一个新的 Contact
作为 AddEntry
。要删除条目,您只需将该数组位置标记为空即可。如您所知,这意味着数组不会随请求动态增长,即您可能需要处理 ArrayFull
情况。此外,您正在进行线性搜索 a.k.a。阵列扫描 - 我假设您不想在此示例中关注该方面。
以下是我对您现有代码的评论:
- 如果
Address
不同,即使 Name
匹配,AddEntry
不应该更新 Address
吗?
- 还 returning 一个
bool
来指示地址是 added/updated(真)还是什么都没做(假)
- 您还应该处理“ArrayFull”条件
- 我不明白你为什么需要变量
existingContact
- 如果您打算 return
bool
,请不要使用名为 CheckXXX
的函数。 ContainxXXX
是更好理解的方法名称,与 bool
return 值一起使用。
- 您不应该
break
从 CheckEntry
中的 foreach
循环。如果添加了 2 个条目,然后第一个条目被删除,然后又请求添加第二个条目怎么办?你会爆发,因为第一个条目是 null
- 您似乎有 3 个不同的
if
可以检查您的 foreach
,其中只有一个就足够了。
下面是我的相关代码和注释。我试图让它们与你所拥有的相似。您可以在多个地方使用 LINQ 而不是循环。
class Contact {
public string Name { get; private set; } // use a property with a private setter, instead of a public member
public string Address { get; private set; } // use a property with a private setter, instead of a public member
public Contact(string name, string address) {
Name = name;
Address = address;
}
}
//------------------------------------------------------------------------
class AddressBook {
public readonly Contact[] contacts;
public AddressBook() {
contacts = new Contact[2]; // I am assuming you kept the size 2 for testing
}
public bool AddEntry(string name, string address) {
if (!ContainsEntry(name)) {
Contact AddContact = new Contact(name, address);
for (int i = 0; i < contacts.Length; i++) {
if (contacts[i] == null) {
contacts[i] = AddContact;
Console.WriteLine("Address Book updated. {0} has been added!", name);
return true;
}
}
Console.WriteLine($"Cannot add name ({name}) to Address Book since it is full!");
// TODO: Throw some exception or specific return values to indicate the same to the caller
} else {
Console.WriteLine($"Name ({name}) already exists in Address Book!");
// TODO: Update the address?
}
return false;
}
private int GetEntryIndex(string name) {
for (int i = 0; i < contacts.Length; i++) {
if (contacts[i] != null && contacts[i].Name == name)
return i;
}
return -1;
}
private bool ContainsEntry(string name) {
return GetEntryIndex(name) != -1;
}
public void RemoveEntry(string name) {
var index = GetEntryIndex(name);
if (index != -1) {
contacts[index] = null;
Console.WriteLine("{0} removed from contacts", name);
}
}
public string View() {
string contactList = "";
foreach (Contact contact in contacts) {
if (contact == null) {
continue; // Don't break, but simply continue to look further
}
contactList += String.Format("Name: {0} -- Address: {1}" + Environment.NewLine, contact.Name, contact.Address);
}
return contactList;
}
}
编辑:回答 OP 提出的一些问题
Q: AddEntry
的return值怎么办
A:现在,您正在编写代码来练习,但是一旦您开始编写行业标准代码,您很快就会意识到您不知道谁调用了您的函数。永远不要假设(除非方法是私有的)只有你会调用这个函数。目前,您不需要对这个 return 值执行任何操作,但有时您可能想知道您的调用是否确实修改了某些值,或者只是 returned 而没有更改。是为了那个时候。这是一个非常标准的做法。有些人甚至 return enum {NoChange, Added, Updated, Deleted}
而不是 bool
Q:如何减少CheckEntry
函数。
A:
下面我用稍微不同的格式编写了你的函数
private bool CheckEntry(string name) {
foreach (Contact contact in contacts) {
if (contact == null) { // First if
continue;
} else {
if (contact != null && contact.Name != name) { // Second if
continue;
} else {
if (contact.Name == name) { // Third if
return false;
}
}
}
}
return true;
}
对于第一个 if
语句,else
部分是多余的。由于 continue
语句,第二个 if
语句仅在 contact is not null
时命中,取消了对 else
关键字的需要。
因为 contact is not null
当我们命中第二个 if
语句时,检查 contact != null
在第二个 if
中是相当多余的。您可以减少 if 语句如下
if (contact.Name != name) { // Second if
continue;
} else {
if (contact.Name == name) { // Third if
return false;
}
}
同样,您会注意到第三个 if
只有在 contact.Name
与 name
相同时才会命中(否则它会继续)。所以没有必要再次检查。这将减少我们的检查如下
if (contact == null)
continue;
if (contact.Name != name)
continue;
else
return false;
这可以通过组合下面两个 if
语句中的条件来进一步减少
if (contact == null || contact.Name != name)
continue;
else
return false;
这与(否定条件)相同
if (contact != null && contact.Name == name)
return false;
所以你的函数看起来像
private bool CheckEntry(string name) {
foreach (Contact contact in contacts)
if (contact != null && contact.Name == name)
return false;
return true;
}
希望你按照这里的推论
Q:我可能对课程有误解,但是当你在 class 中使用 getter 和 setter 编写属性时,我确实在更新版本中进行了更改,我的印象是创建一个构造函数没有必要,甚至是多余的——class(不确定这是否是正确的术语)有一个内置的默认构造函数,用于你想要的情况添加 属性.
A:正确。只是做事的方式不同。
Q:我喜欢你用 GetEntryIndex() 和 ContainsEntry() 做的事——我很好奇,GetEntryIndex() 和你自己写的不一样吗Array.IndexOf(),但是?有人,无论是我还是某种方法,都必须扫描数组。两个版本都是线性的,所以无论哪种方式,这都是 O(n),对吗? (只是进入一些理论,所以如果我错了请纠正我)。因此,就我的理解而言,这与以下内容相同: return Array.IndexOf(contacts, name);这个 returns -1 如果它不存在或者索引是什么(我假设)
A:不一样,但本质相似。 IndexOf
有一套规则来判断给定的两个对象是否是 equal
。您尚未在自定义对象上定义这些规则,因此它将始终为 return -1。有一些简单的 LINQ 语句可以执行这些操作,但我会让您自行探索。
首先,感谢您抽出宝贵时间做出如此详尽的回复。其次,我可能应该指出,我正在教授 myself/taking 一门关于 Treehouse 的课程,并且我正在学习该课程的第二 week/second 部分 - 只是为了让您了解我来自哪里。话虽这么说,我想了解一下您提供给我的内容以及我在这个项目中的目标,以便我可以学习。
- 我同意用户应该能够更新,这是我考虑过但还没有完全实现的功能。
- if returning a bool when added/updated 你会删除更新字符串并将其与调用者放在 main() 中吗?这样它只会在 return true 时打印它已更新,否则打印联系人未更改。感觉制作一个只适合检查值的 class 可能是有利的——这也会使我的代码更可重用?如果我打算在 Main() 中使用它,也许像这样的东西会起作用..
if(!addEntry()) {Console.WriteLine("Contact {0} was not updated", name);} //做点什么
else{Console.WriteLine("Address Book updated. {0} has been added!", 姓名);}
此外,如果用户只是更新联系人,它可以打印它已更新。所以控制台输出可能是一个三元操作——如果添加了新名称打印联系人,否则联系人更新了??
- 我同意并且 运行 遇到了因为阵列已满而什么也没做的情况,这是我计划进行的工作。
- 我完全同意现有的联系人变量。当谈到该怎么做时,我陷入了困境,这是我能想到的最好的。我应该走远一点,多考虑一下。我不知道你是否看到我更新的部分,但我能够消除它。
- 包含一个 bool 方法似乎合乎逻辑,我一定会遵循这个规则。
- 在你这么说之前我没有考虑过这个问题。不过,这是完全有道理的。如果第一个条目为 null 而第二个条目包含用户试图输入的名称,那么你最终会得到一个重复项,因为我在 null 的第一个实例处从循环中跳出,而不是确保该名称不存在在整个阵列中,第一。
- 我不确定,如果没有您的方法,我将如何消除我的三个条件。我知道你做了什么来使这个工作成功,但我可能遗漏了什么吗?或者,更多的是引用说,好的,这是一个更好的方法 - 使用这些方法检查然后消除 if/else 链,从而使您的代码更简洁。
您的代码:
我可能对课程有误解,但是当你用 getter 和 setter 在 class 中编写属性时,我确实在更新版本中进行了更改,我的印象是创建一个构造函数没有必要,甚至是多余的——class(不确定这是否是正确的术语)有一个内置的默认构造函数,用于您想要添加 属性 的情况.
正确,出于测试目的,我确实将大小设置为 2。
我喜欢您对 GetEntryIndex() 和 ContainsEntry() 所做的工作 - 我很好奇,GetEntryIndex() 与编写您自己的 Array.IndexOf() 不同吗?有人,无论是我还是某种方法,都必须扫描数组。两个版本都是线性的,所以无论哪种方式,这都是 O(n),对吗? (只是进入一些理论,所以如果我错了请纠正我)。因此,就我的理解而言,这与:
相同
return Array.IndexOf(联系人,姓名);
这个 returns -1 如果它不存在或者索引是什么(我假设)
- View() 中的 continue 是个好主意。这将确保打印出索引高于空值索引的任何联系人。神奇的是,它以这种方式与 break 一起工作(即使索引 0 为空,它也会打印出索引 1),但我确实意识到为什么不应该这样做以及如何使用 continue 更好。
我是 c# 的新手,正在处理我的第一个项目 - 一个控制台应用程序。我无法理解为什么当地址簿中的条目已经存在时我的代码不会 return false。以下方法都是 AddressBook 的一部分 class CheckEntry(), AddEntry(), RemoveEntry().
好的,所以布尔方法 CheckEntry() 被其他两种方法使用 - AddEntry() 和 RemoveEntry() - 两者都希望在执行各自的职责之前验证用户条目是否存在。在 AddEntry() 中,应该在添加另一个联系人之前查看联系人是否已经存在,如果存在则不应创建联系人(但它会添加重复项)。 RemoveEntry() 应该检查它是否存在并使用 CheckEntry() 中存储变量的更新值来删除当前联系人(但什么也不做)。 我知道我可能要么遗漏了一些简单的东西,要么对整个过程进行了深思熟虑。我的假设是 checkEntry() 无法正常工作,因为与其相关的两个函数都出现故障。谁有想法??让我知道是否需要进一步解释。
注意:我知道使用列表会更好 efficient/easier。我的目标是将数组用于学习目的。从学习 Javascript 切换到 C# 一直是一个挑战,我想确保我在学习下一件事之前学习了每一件事。
这是我的全部代码。每个 class 由“//--------”分隔 在此先感谢您的帮助。
namespace AddressBook {
class Contact {
public string Name;
public string Address;
public Contact(string name, string address) {
Name = name;
Address = address;
}
}
}
//------------------------------------------------------------------------
using System;
namespace AddressBook {
class AddressBook {
public readonly Contact[] contacts;
public AddressBook() {
contacts = new Contact[2]; ;
}
public void AddEntry(string name, string address) {
Contact AddContact = new Contact(name, address);
if (CheckEntry(name)) {
for (int i = 0; i < contacts.Length; i++) {
if (contacts[i] == null) {
contacts[i] = AddContact;
Console.WriteLine("Address Book updated. {0} has been added!", name);
break;
}
}
}
}
private string existingContact = "";
private bool CheckEntry(string name) {
foreach(Contact contact in contacts) {
if (contact == null) {
break;
}
else if (contact != null && contact.ToString() != name) {
continue;
}
else if (contact.ToString() == name) {
existingContact = contact.ToString();
return false;
}
}
return true;
}
public void RemoveEntry(string name) {
if( !(CheckEntry(name)) ) {
existingContact = null;
Console.WriteLine("{0} removed from contacts", name);
}
}
public string View() {
string contactList = "";
foreach(Contact contact in contacts) {
if(contact == null) {
break;
}
contactList += String.Format("Name: {0} -- Address: {1}" + Environment.NewLine, contact.Name, contact.Address);
}
return contactList;
}
}
}
//------------------------------------------------------------------------
using System;
namespace AddressBook {
class Program {
static void Main(string[] args) {
AddressBook addressBook = new AddressBook();
PromptUser();
void Menu() {
Console.WriteLine("TYPE:");
Console.WriteLine("'Add' to add a contact: ");
Console.WriteLine("'Remove' to select and remove a contact: ");
Console.WriteLine("'Quit' to exit: ");
}
void UpdateAddressBook(string userInput) {
string name = "";
string address = "";
switch ( userInput.ToLower() ) {
case "add":
Console.Write("Enter a name: ");
name = Console.ReadLine();
Console.Write("Enter an address: ");
address = Console.ReadLine();
addressBook.AddEntry(name, address);
break;
case "remove":
Console.Write("Enter a name to remove: ");
name = Console.ReadLine();
addressBook.RemoveEntry(name);
break;
case "view":
Console.WriteLine(addressBook.View());
break;
}
}
void PromptUser() {
Menu();
string userInput = "";
while (userInput != "quit") {
Console.WriteLine("What would you like to do?");
userInput = Console.ReadLine();
UpdateAddressBook(userInput);
}
}
}
}
}
这是我想出的 - 经过测试的更改
现在我不能添加重复的名字,我可以删除条目。
public void AddEntry(string name, string address) {
Contact AddContact = new Contact(); //changed
AddContact.Name = name; //changed
AddContact.Address = address; //changed
if (CheckEntry(name)) {
for(int i = 0; i < contacts.Length; i++) {
if (contacts[i] == null) {
contacts[i] = AddContact;
Console.WriteLine("Address Book updated. {0} has been added!", name);
break;
}
}
}
}
//changed - removed variable and all instances of...
private bool CheckEntry(string name) {
foreach(Contact contact in contacts) {
if (contact == null) {
break;
}
else if (contact != null && contact.Name != name) {
continue;
}
else if (contact.Name == name) {
return false;
}
}
return true;
}
//changed - instead of passing checkentry() as a check I just took care of it here
public void RemoveEntry(string name) {
for(int i = 0; i < contacts.Length; i++) {
if(contacts[i].Name == name) {
contacts[i] = null;
break;
}
}
Console.WriteLine("{0} removed from contacts", name);
}
在 CheckEntry 中,您正在使用字符串类型的参数测试 Contact 类型的对象。这无法工作,因为您正在测试 2 种不同的类型。 如果您覆盖 Contact class 中的 ToString 方法(以便它提供属性 contact.name),它可能会按照您编写的方式工作。
您可以像这样修改您的代码(使用 System.Linq 添加):
private bool CheckEntry(string name)
{
return contacts.Any(a => a.Name == name);
}
首先,我假设您的策略是找到数组中的第一个空槽并在其中插入一个新的 Contact
作为 AddEntry
。要删除条目,您只需将该数组位置标记为空即可。如您所知,这意味着数组不会随请求动态增长,即您可能需要处理 ArrayFull
情况。此外,您正在进行线性搜索 a.k.a。阵列扫描 - 我假设您不想在此示例中关注该方面。
以下是我对您现有代码的评论:
- 如果
Address
不同,即使Name
匹配,AddEntry
不应该更新Address
吗? - 还 returning 一个
bool
来指示地址是 added/updated(真)还是什么都没做(假) - 您还应该处理“ArrayFull”条件
- 我不明白你为什么需要变量
existingContact
- 如果您打算 return
bool
,请不要使用名为CheckXXX
的函数。ContainxXXX
是更好理解的方法名称,与bool
return 值一起使用。 - 您不应该
break
从CheckEntry
中的foreach
循环。如果添加了 2 个条目,然后第一个条目被删除,然后又请求添加第二个条目怎么办?你会爆发,因为第一个条目是null
- 您似乎有 3 个不同的
if
可以检查您的foreach
,其中只有一个就足够了。
下面是我的相关代码和注释。我试图让它们与你所拥有的相似。您可以在多个地方使用 LINQ 而不是循环。
class Contact {
public string Name { get; private set; } // use a property with a private setter, instead of a public member
public string Address { get; private set; } // use a property with a private setter, instead of a public member
public Contact(string name, string address) {
Name = name;
Address = address;
}
}
//------------------------------------------------------------------------
class AddressBook {
public readonly Contact[] contacts;
public AddressBook() {
contacts = new Contact[2]; // I am assuming you kept the size 2 for testing
}
public bool AddEntry(string name, string address) {
if (!ContainsEntry(name)) {
Contact AddContact = new Contact(name, address);
for (int i = 0; i < contacts.Length; i++) {
if (contacts[i] == null) {
contacts[i] = AddContact;
Console.WriteLine("Address Book updated. {0} has been added!", name);
return true;
}
}
Console.WriteLine($"Cannot add name ({name}) to Address Book since it is full!");
// TODO: Throw some exception or specific return values to indicate the same to the caller
} else {
Console.WriteLine($"Name ({name}) already exists in Address Book!");
// TODO: Update the address?
}
return false;
}
private int GetEntryIndex(string name) {
for (int i = 0; i < contacts.Length; i++) {
if (contacts[i] != null && contacts[i].Name == name)
return i;
}
return -1;
}
private bool ContainsEntry(string name) {
return GetEntryIndex(name) != -1;
}
public void RemoveEntry(string name) {
var index = GetEntryIndex(name);
if (index != -1) {
contacts[index] = null;
Console.WriteLine("{0} removed from contacts", name);
}
}
public string View() {
string contactList = "";
foreach (Contact contact in contacts) {
if (contact == null) {
continue; // Don't break, but simply continue to look further
}
contactList += String.Format("Name: {0} -- Address: {1}" + Environment.NewLine, contact.Name, contact.Address);
}
return contactList;
}
}
编辑:回答 OP 提出的一些问题
Q: AddEntry
的return值怎么办
A:现在,您正在编写代码来练习,但是一旦您开始编写行业标准代码,您很快就会意识到您不知道谁调用了您的函数。永远不要假设(除非方法是私有的)只有你会调用这个函数。目前,您不需要对这个 return 值执行任何操作,但有时您可能想知道您的调用是否确实修改了某些值,或者只是 returned 而没有更改。是为了那个时候。这是一个非常标准的做法。有些人甚至 return enum {NoChange, Added, Updated, Deleted}
而不是 bool
Q:如何减少CheckEntry
函数。
A: 下面我用稍微不同的格式编写了你的函数
private bool CheckEntry(string name) {
foreach (Contact contact in contacts) {
if (contact == null) { // First if
continue;
} else {
if (contact != null && contact.Name != name) { // Second if
continue;
} else {
if (contact.Name == name) { // Third if
return false;
}
}
}
}
return true;
}
对于第一个 if
语句,else
部分是多余的。由于 continue
语句,第二个 if
语句仅在 contact is not null
时命中,取消了对 else
关键字的需要。
因为 contact is not null
当我们命中第二个 if
语句时,检查 contact != null
在第二个 if
中是相当多余的。您可以减少 if 语句如下
if (contact.Name != name) { // Second if
continue;
} else {
if (contact.Name == name) { // Third if
return false;
}
}
同样,您会注意到第三个 if
只有在 contact.Name
与 name
相同时才会命中(否则它会继续)。所以没有必要再次检查。这将减少我们的检查如下
if (contact == null)
continue;
if (contact.Name != name)
continue;
else
return false;
这可以通过组合下面两个 if
语句中的条件来进一步减少
if (contact == null || contact.Name != name)
continue;
else
return false;
这与(否定条件)相同
if (contact != null && contact.Name == name)
return false;
所以你的函数看起来像
private bool CheckEntry(string name) {
foreach (Contact contact in contacts)
if (contact != null && contact.Name == name)
return false;
return true;
}
希望你按照这里的推论
Q:我可能对课程有误解,但是当你在 class 中使用 getter 和 setter 编写属性时,我确实在更新版本中进行了更改,我的印象是创建一个构造函数没有必要,甚至是多余的——class(不确定这是否是正确的术语)有一个内置的默认构造函数,用于你想要的情况添加 属性.
A:正确。只是做事的方式不同。
Q:我喜欢你用 GetEntryIndex() 和 ContainsEntry() 做的事——我很好奇,GetEntryIndex() 和你自己写的不一样吗Array.IndexOf(),但是?有人,无论是我还是某种方法,都必须扫描数组。两个版本都是线性的,所以无论哪种方式,这都是 O(n),对吗? (只是进入一些理论,所以如果我错了请纠正我)。因此,就我的理解而言,这与以下内容相同: return Array.IndexOf(contacts, name);这个 returns -1 如果它不存在或者索引是什么(我假设)
A:不一样,但本质相似。 IndexOf
有一套规则来判断给定的两个对象是否是 equal
。您尚未在自定义对象上定义这些规则,因此它将始终为 return -1。有一些简单的 LINQ 语句可以执行这些操作,但我会让您自行探索。
首先,感谢您抽出宝贵时间做出如此详尽的回复。其次,我可能应该指出,我正在教授 myself/taking 一门关于 Treehouse 的课程,并且我正在学习该课程的第二 week/second 部分 - 只是为了让您了解我来自哪里。话虽这么说,我想了解一下您提供给我的内容以及我在这个项目中的目标,以便我可以学习。
- 我同意用户应该能够更新,这是我考虑过但还没有完全实现的功能。
- if returning a bool when added/updated 你会删除更新字符串并将其与调用者放在 main() 中吗?这样它只会在 return true 时打印它已更新,否则打印联系人未更改。感觉制作一个只适合检查值的 class 可能是有利的——这也会使我的代码更可重用?如果我打算在 Main() 中使用它,也许像这样的东西会起作用..
if(!addEntry()) {Console.WriteLine("Contact {0} was not updated", name);} //做点什么 else{Console.WriteLine("Address Book updated. {0} has been added!", 姓名);}
此外,如果用户只是更新联系人,它可以打印它已更新。所以控制台输出可能是一个三元操作——如果添加了新名称打印联系人,否则联系人更新了??
- 我同意并且 运行 遇到了因为阵列已满而什么也没做的情况,这是我计划进行的工作。
- 我完全同意现有的联系人变量。当谈到该怎么做时,我陷入了困境,这是我能想到的最好的。我应该走远一点,多考虑一下。我不知道你是否看到我更新的部分,但我能够消除它。
- 包含一个 bool 方法似乎合乎逻辑,我一定会遵循这个规则。
- 在你这么说之前我没有考虑过这个问题。不过,这是完全有道理的。如果第一个条目为 null 而第二个条目包含用户试图输入的名称,那么你最终会得到一个重复项,因为我在 null 的第一个实例处从循环中跳出,而不是确保该名称不存在在整个阵列中,第一。
- 我不确定,如果没有您的方法,我将如何消除我的三个条件。我知道你做了什么来使这个工作成功,但我可能遗漏了什么吗?或者,更多的是引用说,好的,这是一个更好的方法 - 使用这些方法检查然后消除 if/else 链,从而使您的代码更简洁。
您的代码:
我可能对课程有误解,但是当你用 getter 和 setter 在 class 中编写属性时,我确实在更新版本中进行了更改,我的印象是创建一个构造函数没有必要,甚至是多余的——class(不确定这是否是正确的术语)有一个内置的默认构造函数,用于您想要添加 属性 的情况.
正确,出于测试目的,我确实将大小设置为 2。
我喜欢您对 GetEntryIndex() 和 ContainsEntry() 所做的工作 - 我很好奇,GetEntryIndex() 与编写您自己的 Array.IndexOf() 不同吗?有人,无论是我还是某种方法,都必须扫描数组。两个版本都是线性的,所以无论哪种方式,这都是 O(n),对吗? (只是进入一些理论,所以如果我错了请纠正我)。因此,就我的理解而言,这与:
相同
return Array.IndexOf(联系人,姓名);
这个 returns -1 如果它不存在或者索引是什么(我假设)
- View() 中的 continue 是个好主意。这将确保打印出索引高于空值索引的任何联系人。神奇的是,它以这种方式与 break 一起工作(即使索引 0 为空,它也会打印出索引 1),但我确实意识到为什么不应该这样做以及如何使用 continue 更好。