C# 在IEquatable上重写Equals
我尝试使用以下方法阻止人们更改C# 在IEquatable上重写Equals,c#,.net,entity-framework,C#,.net,Entity Framework,我尝试使用以下方法阻止人们更改查询字符串,以查看其他人的详细信息: public static bool IsCurrentUserAuthorisedVessel(HttpRequest request) { Guid currentUser = GetCurrentUserId(); PersonRepository repo = new PersonRepository(); VesselRepository vesselRepo = new VesselRepos
查询字符串
,以查看其他人的详细信息:
public static bool IsCurrentUserAuthorisedVessel(HttpRequest request)
{
Guid currentUser = GetCurrentUserId();
PersonRepository repo = new PersonRepository();
VesselRepository vesselRepo = new VesselRepository();
Person currentPerson = repo.GetPersonByUser(currentUser);
int qs = int.Parse(request.QueryString["VesselId"]);
Vessel currentVessel = vesselRepo.GetVessel(qs);
if (!String.IsNullOrEmpty(request.QueryString["VesselId"]))
{
if (IsCurrentUserAdmin())
{
return true; //Always return true for admin
}
else
{
if (currentPerson.Vessels.Contains(currentVessel))
{
return true;
}
else
return false;
}
}
return true;
}
在本例中,我当前正在调试currentPerson.Vessels
在I集合中生成3个Vessels
其中一个的VesselId
为6,它恰好也是currentVessel
的VesselId,但是匹配失败,方法返回false
我已经阅读了一些类似的SO问题和MSDN文档,我对这里发生的事情的理解是因为ICollection中ID为6的容器是我试图匹配的当前容器的不同实例,引用导致不相等,与相等规则有关的内容不基于ID
我的Person
模型包含公共虚拟ICollection容器{get;set;}
这是否意味着我必须在我的容器
模型上实现IEquatable
接口,然后覆盖Equals方法
在这个例子中,我需要基于id的自定义规则来实现相等。如何重写此方法?重写
Equals
在这种情况下似乎有点过火,为什么不这样做呢
currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)
在这种情况下重写
等于
似乎有点过分,为什么不这样做呢
currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)
改变
if (currentPerson.Vessels.Contains(currentVessel))
{
return true;
}
else
return false;
到
改变
if (currentPerson.Vessels.Contains(currentVessel))
{
return true;
}
else
return false;
到
@james建议的解决方案不是最佳实践。 在这里,为什么如果你有一长串应该添加到
Hashset
contains方法中的容器,那么它只需要O(1)
,因为它将在GetHashCode
上被索引,而。Any
是一个扩展方法,它应该遍历所有元素以找到正确的一个,并且成本将是O(n)
你可以这样做
public class Vessel : IEquatable<Vessel>
{
public int Id { get; set; }
public bool Equals(Vessel other)
{
return Id == other.Id ;
}
public override int GetHashCode()
{
return Id;
}
public override bool Equals(object obj)
{
var vessel = obj as Vessel;
return vessel != null && vessel.Id == this.Id;
}
}
公共级船舶:合格
{
公共int Id{get;set;}
公共布尔等于(其他船舶)
{
返回Id==other.Id;
}
公共覆盖int GetHashCode()
{
返回Id;
}
公共覆盖布尔等于(对象对象对象)
{
var血管=obj血管;
返回容器!=null&&vesser.Id==this.Id;
}
}
更新
我之所以说这不是最佳实践,是因为OP说他有一个ICollection
,可以转换为许多泛型集合,例如List
从
调用多个通用集合对象的搜索方法时。其中一些类型及其方法包括:
- BinarySearch方法的一些泛型重载
- List类的搜索方法,包括List.Contains(T)、List.IndexOf、List.LastIndexOf和List.Remove
- Dictionary类的搜索方法,包括ContainsKey和Remove。 泛型LinkedList类的搜索方法,包括LinkedList.Contains和Remove
- 由@james建议的解决方案不是最佳实践。
在这里,为什么如果你有一长串应该添加到
Hashset
contains方法中的容器,那么它只需要O(1)
,因为它将在GetHashCode
上被索引,而。Any
是一个扩展方法,它应该遍历所有元素以找到正确的一个,并且成本将是O(n)
你可以这样做
public class Vessel : IEquatable<Vessel>
{
public int Id { get; set; }
public bool Equals(Vessel other)
{
return Id == other.Id ;
}
public override int GetHashCode()
{
return Id;
}
public override bool Equals(object obj)
{
var vessel = obj as Vessel;
return vessel != null && vessel.Id == this.Id;
}
}
公共级船舶:合格
{
公共int Id{get;set;}
公共布尔等于(其他船舶)
{
返回Id==other.Id;
}
公共覆盖int GetHashCode()
{
返回Id;
}
公共覆盖布尔等于(对象对象对象)
{
var血管=obj血管;
返回容器!=null&&vesser.Id==this.Id;
}
}
更新
我之所以说这不是最佳实践,是因为OP说他有一个ICollection
,可以转换为许多泛型集合,例如List
从
调用多个通用集合对象的搜索方法时。其中一些类型及其方法包括:
- BinarySearch方法的一些泛型重载
- List类的搜索方法,包括List.Contains(T)、List.IndexOf、List.LastIndexOf和List.Remove
- Dictionary类的搜索方法,包括ContainsKey和Remove。 泛型LinkedList类的搜索方法,包括LinkedList.Contains和Remove
return Id==other.Id
,对象为return toreturn vessel!=空和等于(容器)
。代码更少,逻辑也不会重复。声称使用Any
这里的“不是一个好的解决方案”或“不是最佳实践”是毫无意义的。实现Equals
的参数当然是有效的,但前提是性能/列表大小是OP没有提到的一个因素。将键入的Equals简化为:return Id==other.Id
并且对象等于return toreturn vessel!=空和等于(容器)
。代码更少,逻辑也不会重复。声称使用Any
这里的“不是一个好的解决方案”或“不是最佳实践”是毫无意义的。实现Equals
的参数当然是有效的,但只有当perfo