Есть ли что-то вроде анонимных внутренних классов (используемых в Java) в C #?
Я объясняю, для чего я буду использовать это на примере: я объявляю и инициализирую поле типа IDictionary<Person, Account>
, и мне нужно написать custom IEqualityComparer<Person>
. Это потому, что я хочу, чтобы два персонажа рассматривались как равные IDictionary, когда они имеют одинаковые имена и идентификаторы (не только идентификаторы, как это по умолчанию). Мне не понадобится этот 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
два Color
считаются равными, когда все их свойства (кроме Id
) равны.
Теперь, если я использую решение, которое Джон Скит любезно порекомендовал мне, я не уверен, что это можно обеспечить.
Если бы я использовал что-то вроде:
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)
, он не будет сравнивать Color
с, как я хочу (используя все свойства, кроме Id
), поэтому равенство Font
с будет проверено неправильно. Я прав?