我正在嘗試實作記錄型別以使比較不那么復雜。但是我在比較記錄時遇到了問題。當屬性彼此相等時,我希望記錄相等,但在我的代碼中并非如此。
我有一個MyAlarm帶有一些屬性的記錄類。它繼承自IAlarm空的介面。
public record MyAlarm : IAlarm
{
public int Prop1 { get; init; }
public int Prop2 { get; init; }
}
一個名為的類VisibleAlarm具有 IAlarm 作為屬性以及一些額外的資料。
public record VisibleAlarm
{
public IAlarm InternalAlarm { get; init; }
public string Message { get; set; }
}
在一個名為AlarmServiceVisibleAlarms 的類中列出并在需要時更新。該服務有一個可見警報串列。
此外,在此警報服務中,根據 IAlarm 屬性檢查串列是否已存在警報。我嘗試了兩種方法:
public class AlarmService
{
private List<VisibleAlarm> _alarms = new();
// ... Other code that handles alarm stuff
private VisibleAlarm GetExistingAlarm1(IAlarm alarm)
{
return _alarms.FirstOrDefault(a => a.InternalAlarm == alarm);
}
private VisibleAlarm GetExistingAlarm2(IAlarm alarm)
{
foreach (var existingAlarm in _alarms)
{
if (existingAlarm.InternalAlarm == alarm)
{
return existingAlarm;
}
}
}
}
在除錯代碼時,我看到 existingAlarm.InternalAlarm 的記錄屬性和給定的警報匹配,但這些GetExistingAlarm方法仍然回傳 false。由于介面 IAlarm,我是否遺漏了什么或者我必須實作 IEqualityComparer?
干杯
uj5u.com熱心網友回復:
在您的代碼行中:
return _alarms.FirstOrDefault(a => a.InternalAlarm == alarm);
是a.InternalAlarm == alarm呼叫operator==而不是object.Equals()進行比較。
您可以通過將代碼更改為:
return _alarms.FirstOrDefault(a => a.InternalAlarm.Equals(alarm));
以下程式演示了差異:
using System;
static class Program
{
public static void Main()
{
MyAlarm ma1 = new MyAlarm { Prop1 = 1, Prop2 = 2 };
MyAlarm ma2 = new MyAlarm { Prop1 = 1, Prop2 = 2 };
VisibleAlarm va1 = new VisibleAlarm { InternalAlarm = ma1, Message = "message" };
VisibleAlarm va2 = new VisibleAlarm { InternalAlarm = ma2, Message = "message" };
Console.WriteLine(ma1 == ma2); // True
Console.WriteLine(va1 == va2); // True
Console.WriteLine(va1.InternalAlarm == va2.InternalAlarm); // False
Console.WriteLine(va1.InternalAlarm.Equals(va2.InternalAlarm)); // True
}
public interface IAlarm
{
int Prop1 { get; }
int Prop2 { get; }
}
public record MyAlarm : IAlarm
{
public int Prop1 { get; init; }
public int Prop2 { get; init; }
}
public record VisibleAlarm
{
public IAlarm InternalAlarm { get; init; }
public string Message { get; set; }
}
}
輸出:
True
True
False
True
這對您不起作用的原因是因為InternalAlarm是 typeIAlarm而不是MyAlarm. 如果將型別更改為MyAlarm,您將得到比較true而不是false。
這是因為IAlarm沒有定義一個operator==(注意:這樣的運算子將是靜態的)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/446632.html
