【发布时间】:2010-08-22 20:30:48
【问题描述】:
在 C# 中是否有类似匿名内部类(在 Java 中使用)的东西?
我举例说明我会用它做什么:我正在声明和初始化IDictionary<Person, Account> 类型的字段,我需要编写自定义IEqualityComparer<Person>。那是因为我希望 IDictionary 将两个 Person 视为相同,因为它们具有相同的名称和 ID(不仅是默认情况下的 ID)。我在代码中的任何其他地方都不需要这个IEqualityComparer<Person>。
所以我是否必须声明实现IEqualityComparer<Person> 的新类才能做到这一点?在 Java 中,我会使用匿名类,类似这样(这是混合的 C#-Java 语法,只是为了显示我正在寻找的功能):
IDictionry<Person, Account> myDict = new Dictionary<Person, Account>(
new IEqualityComparer<Person>(){
public bool Equals(Person a, Person b){
return a.Id == b.Id && a.Name == b.Name;
}
public int GetHashCode(Person p){
return p.Id.GetHashCode() * p.Name.GetHashCode();
}
});
在 C# 中有这样的东西吗?每次我需要这样的东西时,我都懒得写新课程。
注意:这是语法问题。我知道怎么写,但我想知道是否有可能使代码更短。
------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------
编辑:您自己如何编写类似案例的代码?您是创建新类来实现接口还是做什么?也许你有一些我可能会喜欢的技巧。
编辑 未来对匿名类(如 Java 中的那些)的支持如何?你听说过吗?
编辑:好吧,我知道我必须提供我的实际代码 - 而不仅仅是一个示例。那是因为我不知道它是否适用于 Jon's Skeet 的解决方案。
我不只是在类本身中实现Equals(object) 和GetHashCode 的实际原因是,它是E-R 框架从模型图中生成的类(实体)。如果我在类本身中实现它,那么每次我从数据库更新模型(使用“从数据库更新”功能)时,我的代码都会从类(实体)中删除。该类实际上称为Font 而不是Person。它具有以下特性:
Id: int
FamilyName:string
Size:int
Bold:bool
Italic:bool
Underlined:bool
Striked:bool
Foreground:Color
其中Color 是从数据库生成的另一个类(实体)。
这是颜色的属性:
Id:int
Alpha:byte
Red:byte
Green:byte
Blue:byte
所以我不能修改字体,颜色也不能(如果我不想在每次更改数据库时一遍又一遍地重写这些更改)我想要的是拥有这个Dictionary:
private IDictionary<Font, Something> cache = new Dictionary<Font, Something>(new SomeEqualityComparer());
并且比较器SomeEqualityComparer 应该确保当且仅当上面列出的所有属性(Id 除外)都相等时,两个字体才会被视为相等。在最后一个属性Foreground 的情况下,当两个Colors 的所有属性(Id 除外)都相等时,它们被认为是相等的。
现在,如果我使用 Jon Skeet 向我推荐的解决方案,我不确定这是否可以确保。 如果我使用类似的东西:
private IDictionary<Font, Something> cache = new Dictionary<Font, Something>(ProjectionEqualityComparer<Font>.Create
(f => new { f.FontName, f.Size, f.Bold, f.Italic, f.Underlined, f.Striked, f.Foreground});
我猜想匿名类型在调用Equals(object) 时在所有属性上调用Equals(object)。但是,由于我无法覆盖Color 的Equals(object),它不会像我想要的那样比较Colors(使用除Id 之外的所有属性),因此Fonts 的相等性也会被错误地测试。我说的对吗?
【问题讨论】: