我目前正在開發一個 .NET Core 3.1 應用程式。
我需要重構代碼異味以降低方法復雜性——在我的方法中有很多重復的元素。
我班級中的所有屬性都是字串型別。我需要檢查傳遞的參考是否與屬性具有相同的值。如果參考的值不同,我需要將標志設定為 true 并使用參考的值更正屬性值。
public string Name { get; set; }
// ... all Properties are of type String!
public bool MyMethod(Apple myApple)
{
var flag = false;
myApple.Id = Id;
if (Name != myApple.Name)
{
Name = myApple.Name;
flag = true;
}
if (Description != myApple.Description)
{
Description = myApple.Description;
flag = true;
}
if (ShortDescription != myApple.ShortDescription)
{
ShortDescription = myApple.ShortDescription;
flag = true;
}
if (Location != myApple.Location)
{
Location = myApple.Location;
flag = true;
}
if (KindId != myApple.KindId)
{
KindId = myApple.KindId;
flag = true;
}
if (Expiration != myApple.Expiration)
{
Expiration = myApple.Expiration;
flag = true;
}
if (PurchaseDate != myApple.PurchaseDate)
{
PurchaseDate = myApple.PurchaseDate;
flag = true;
}
return flag;
}
你知道如何降低我的方法的復雜性,或許還能擺脫重復的元素嗎?
uj5u.com熱心網友回復:
您可以通過引入一個本地函式并使用一個委托來選擇要比較的屬性并使用另一個委托來分配屬性來縮短它。
它看起來像這樣:
public bool MyMethod(Apple myApple)
{
bool flag = false;
void assignIfDifferent<T>(Func<Apple, T> selector, Action assign)
{
if (EqualityComparer<T>.Default.Equals(selector(myApple), selector(this)))
return;
assign();
flag = true;
}
assignIfDifferent(apple => apple.Name, () => { this.Name = myApple.Name; });
assignIfDifferent(apple => apple.Description, () => { this.Description = myApple.Description; });
assignIfDifferent(apple => apple.ShortDescription, () => { this.ShortDescription = myApple.ShortDescription; });
assignIfDifferent(apple => apple.Location, () => { this.Location = myApple.Location; });
// Etc etc.
return flag;
}
我不太相信這是一種改進,但這由你決定。它至少確實減少了代碼行數。
uj5u.com熱心網友回復:
如果您使用欄位而不是自動屬性,則可以使用以下模式
private string name;
public string Name => name;
public bool MyMethod(Apple myApple)
{
var flag = false;
myApple.Id = Id;
flag |= Set(ref name, myApple.Name);
flag |= Set(ref description , myApple.Description);
...
}
private bool Set<T>(ref T field, T value) where T : IEquatable<T>{
if(!field.Equals(value)){
field = value;
return true;
}
return false;
}
此方法也可以與CallerMemberName結合使用,以幫助為 wpf 代碼引發事件。
使用屬性執行相同的模式不太整潔,因為您需要使用委托來設定值或反射。
uj5u.com熱心網友回復:
您可以使用反射來做到這一點。您可以迭代類的所有屬性并對其進行控制。
var test = (new Apple()).MyMethod(new Apple() { Name = "Stack", Desc = "Test" });
public class Apple
{
public string Name { get; set; } = "Onur";
public string Desc { get; set; } = "Test";
// ... all Properties are of type String
public bool MyMethod(Apple apple)
{
bool flag = false;
IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
foreach (PropertyInfo prop in props)
{
try
{
//get value in method param
object propValue = prop.GetValue(apple, null);
//get current prop in current class
PropertyInfo propResult = this.GetType().GetProperty(prop.Name, BindingFlags.Public | BindingFlags.Instance);
var val = propResult.GetValue(this, null);
if (val != propValue)
{
propResult.SetValue(this, propValue, null);
flag = true;
}
}
catch (Exception ex)
{
}
}
return flag;
}
}
uj5u.com熱心網友回復:
另一種選擇可能是為所有屬性使用類似記錄的東西,即只需使用您想要的所有新屬性創建一個新記錄,然后使用自動生成的相等方法將其與舊記錄進行比較以查看它們是否相等。IE
public record MyProperties(string Name, string Description);
...
private MyProperties props;
public string Name => props.Name;
...
public bool MyMethod(Apple myApple)
{
var newProps = new MyProperties(
myApple.Name,
myApple.Descrpition);
var flag = newProps != props;
props = newProps;
return flag;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/508237.html