C#中的匿名内部类?

Ras*_*sto 8 c# java syntax

在C#中是否存在类似匿名内部类(在Java中使用)的内容?

我通过示例解释了我将使用它的内容:我正在声明并初始化类型字段,IDictionary<Person, Account>我需要编写自定义IEqualityComparer<Person>.这是因为当IDictionary具有相同的名称和ID时,我希望两个人被IDictionary视为相等(默认情况下不仅是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();
        }
    });
Run Code Online (Sandbox Code Playgroud)

在C#中是这样的吗?每次我需要这样的东西时,我都懒得写新课.

注意:这是语法问题.我知道如何编写它,但我想知道是否可以缩短代码.

-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------

编辑:你自己如何编写类似的案件?您是否创建了新类来实现界面,或者您做了什么?也许你有一些我可能喜欢的技巧.

编辑未来对Java等匿名类的支持怎么样?你听说过吗?

编辑:嗯,我发现我必须提供我的实际代码 - 而不仅仅是一个例子.那是因为我不知道它是否适用于Jon的Skeet解决方案.

实际的原因,我不只是落实Equals(object)GetHashCode在类本身,通过从模型图ER框架生成它的类(实体).如果我在类本身实现它,每次从数据库更新模型时都会从类(实体)中删除我的代码(使用"从数据库更新"功能).该类实际上Font不被称为Person.它具有以下特点:

Id: int
FamilyName:string
Size:int
Bold:bool
Italic:bool
Underlined:bool
Striked:bool
Foreground:Color
Run Code Online (Sandbox Code Playgroud)

Color从数据库生成的另一个类(实体)在哪里?

这是颜色的属性:

Id:int
Alpha:byte
Red:byte
Green:byte
Blue:byte
Run Code Online (Sandbox Code Playgroud)

所以我不能修改Font,也不能修改Color(如果我不想每次更改数据库时反复重写这些更改)我想要的是Dictionary:

private IDictionary<Font, Something> cache = new Dictionary<Font, Something>(new SomeEqualityComparer());
Run Code Online (Sandbox Code Playgroud)

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});
Run Code Online (Sandbox Code Playgroud)

我猜测匿名类型会在调用Equals(object)它们时调用所有属性Equals(object).但是,我不能覆盖ColorEquals(object)它不会比较Color,因为我想秒(使用除所有属性Id),所以也平等Fonts就被错误地检测.我对吗 ?

Jon*_*eet 13

我有一个ProjectionEqualityComparer你可以在MiscUtil中使用的类.你会使用这样的代码:

IEqualityComparer<Person> comparer = ProjectionEqualityComparer<Person>.Create
    (p => new { p.Name, p.Id });
Run Code Online (Sandbox Code Playgroud)

这使用了匿名类型具有内置适当的相等概念的事实 - 当ProjectionEqualityComparer要求比较两个人的相等性时,它会将每个人投射到匿名类型,并比较这些实例.同样,当它被要求提供哈希码时,它将执行投影并询问其哈希码.

编辑:为了解决你的颜色问题,你是对的:如果Color没有以你想要的方式覆盖Equals/GetHashCode,你就不能直接使用它.但是,您可以这样做:

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.Alpha, f.Foreground.Red, f.Foreground.Green,
        f.Foreground.Blue});
Run Code Online (Sandbox Code Playgroud)

如果你能够Color根据属性修改类型,那么如果你能给它一个从其他人生成的ARGB属性会更简单,所以你可以写:

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.ARGB });
Run Code Online (Sandbox Code Playgroud)

那很难看,但应该有效......


Dr.*_*ice 3

在上次编辑中,您提到不实现 Equals 和 GetHashCode 的原因是因为类的代码是自动生成的,并且您不希望每次重新生成代码时都重新实现该代码。

这是C# 中引入分部类的场景之一

许多代码生成工具将生成带有partial关键字的类,以允许您利用该功能。检查为您的代码生成的类是否不完整。

在同一程序集中重新生成代码时不会被覆盖的单独文件(或多个文件)中,您可能会具有如下内容:

partial class Font
{
    public override bool Equals(object obj)
    {
        // ...
    }

    public override int GetHashCode()
    {
        // ...
    }
}

partial class Color
{
    public override bool Equals(object obj)
    {
        // ...
    }

    public override int GetHashCode()
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)