我的問題與字典的使用有關。我將嘗試附上代碼,然后解釋我的疑問:
var ambassadors = new Dictionary<CountryCode, Ambassador>();
Ambassador england = new Ambassador
{
CountryCode = new CountryCode("eng"),
Name = "John",
Age = 25
};
Ambassador australia = new Ambassador
{
CountryCode = new CountryCode("aus"),
Name = "Martin",
Age = 49
};
ambassadors.Add(england.CountryCode, england);
ambassadors.Add(australia.CountryCode, australia);
Console.WriteLine("Enter country code: ");
var code = Console.ReadLine();
if (ambassadors.TryGetValue(new CountryCode(code), out Ambassador ambassador))
{
Console.WriteLine($"The ambassador is {ambassador.Name}");
}
else
{
Console.WriteLine("The ambassador with the given code does not exist in the dictonary");
}
Console.ReadLine();
}
public class Ambassador
{
public CountryCode CountryCode { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public class CountryCode
{
public string Code { get; }
public CountryCode(string code)
{
Code = code;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (!(obj is CountryCode))
{
return false;
}
return StringComparer.OrdinalIgnoreCase.Equals(this.Code, ((CountryCode)obj).Code);
}
public override int GetHashCode()
{
return StringComparer.OrdinalIgnoreCase.GetHashCode(this.Code);
}
我的疑問與我使用的行有關
ambassadors.TryGetValue
if 中的方法來檢查密鑰并將值回傳給我。我的問題是:為什么要在 TryGetValue 中創建 Class CountrySide 的新實體(或初始化)?
我的意思是大使字典中已經存在該類的實體。那么,為什么 c# 要求我在 TryGetValue 方法中初始化一個新的,而不是簡單地檢查一個特定的是否存在,而在 CoutryCode(code) 之前沒有“新”?
如果你能澄清我這個概念,我將不勝感激。
uj5u.com熱心網友回復:
恕我直言,您不需要 CountryCode 類,字串型別就足夠了
var ambassadors = new Dictionary<string, Ambassador>();
public class Ambassador
{
public string CountryCode { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
....
Ambassador england = new Ambassador
{
CountryCode = "eng",
Name = "John",
Age = 25
};
if ( ambassadors.TryGetValue(code, out var ambassador))
{
Console.WriteLine($"The ambassador is {ambassador.Name}");
}
else
{
Console.WriteLine($"The ambassador with the given code \"{code}\" does not exist in the dictonary");
}
// or you can use this too
if (ambassadors.ContainsKey(code))
{
Console.WriteLine($"The ambassador is {ambassadors[code].Name}");
}
else
{
Console.WriteLine($"The ambassador with the given code \"{code}\" does not exist in the dictonary");
}
如果由于某些原因您需要 CountryCode 類,恕我直言,最好以這種方式定義字典。在這種情況下,您可能不需要 CountryCode 類的 bool Equals(object obj) 方法。
var ambassadors = new Dictionary<string, Ambassador>();
您可以通過這種方式將專案添加到字典
Ambassador england = new Ambassador
{
CountryCode = new CountryCode("eng"),
Name = "John",
Age = 25
};
Ambassador australia = new Ambassador
{
CountryCode = new CountryCode("aus"),
Name = "Martin",
Age = 49
};
ambassadors.Add(england.CountryCode.Code, england);
ambassadors.Add(australia.CountryCode.Code, australia);
所有其他代碼都將與我在上面發布的相同
uj5u.com熱心網友回復:
其他答案和評論已經對此進行了詳細說明:您的字典被鍵入CountryCode,因此需要一個CountryCode實體,因此需要newin
ambassadors.TryGetValue(new CountryCode(code), out var ambassador)
我想在這里評論一個不同的角度:雖然您可以將字典設為鍵string,然后使用
var ambassadors = new Dictionary<string, Ambassador>(StringComparer.OrdinalIgnoreCase);
// ...
ambassadors.TryGetValue(code, out var ambassador)
直接地,它需要泄露有關如何比較國家代碼的知識 - 請注意其中StringComparer.OrdinalIgnoreCase的內容。
CountryCode我相信改為 a可能會有好處struct:
public readonly struct CountryCode
{
public string Code { get; }
// ...
}
這將保留所有驗證代碼 - 即,型別建構式仍然可以檢查某些內容是否是有效的國家代碼,而不是 null 或空格等 - 但它將節省分配資源:由于 astruct是值型別,因此new分配在堆疊上而不是在堆上,因此就您在此處的使用而言幾乎是免費的。
關鍵部分——你已經擁有了——是擁有Equals和GetHashCode設定。如上所述,Equals這里很重要,因為它允許將對待兩者eng視為ENG相似。鑒于此,任何由 a 鍵入的型別CountryCode都不需要知道或關心等同于兩個國家/地區代碼的細節,這比stringkey 有很大的好處。
為了可用性,我建議也實作IEquatable<CountryCode>介面,以及operator ==和operator !=多載:
public readonly struct CountryCode : IEquatable<CountryCode>
{
// Note: `default(CountryCode)` will not call the constructor!
private readonly string? _code;
public CountryCode(string code)
{
// Verify country codes, throw exceptions, ...
_code = code?.Trim().ToLowerInvariant() ?? throw new ArgumentNullException(nameof(code));
}
// Note: ensure proper values for `default(CountryCode)`.
public string Code => _code ?? string.Empty;
public bool Equals(CountryCode other) =>
StringComparer.OrdinalIgnoreCase.Equals(Code, other);
public override bool Equals(object? obj) =>
obj is CountryCode other && Equals(other);
public override int GetHashCode() =>
StringComparer.OrdinalIgnoreCase.GetHashCode(Code);
public static bool operator ==(CountryCode lhs, CountryCode rhs) =>
lhs.Equals(rhs);
public static bool operator !=(CountryCode lhs, CountryCode rhs) =>
!lhs.Equals(rhs);
}
如果您正在處理常用名稱,我在將建構式設為私有并命名值方面取得了一些成功,如下所示:
public readonly struct CountryCode : IEquatable<CountryCode>
{
public static readonly CountryCode Empty = default;
public static readonly CountryCode England = new("eng");
public static readonly CountryCode Australia = new("aus");
// ...
}
大多數反序列化代碼仍會使用私有建構式,但任何應用程式代碼都將被迫使用允許的值。這可能對您的情況有用,也可能沒有用。
請注意,也可以使用這樣的string轉換運算子:
public static implicit operator string(CountryCode code) =>
code.Code;
不過,顯式 ( var code = countryCode.Code) 通常比隱式 ( ) 更好var code = countryCode,因此請謹慎對待。
所以我在這里的建議是:
- 堅持用
CountryCode鑰匙, - make
CountryCodeareadonly struct而不是 aclass,這使它更好更快 - 注意
default(CountryCode)實體,因為它們不會呼叫建構式;在class型別中,整個值將是null。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/410051.html
標籤:
下一篇:Ansible變數插值
