为什么我的一些类名在新的 VS 2015 编译器中返回为“<>c”?

Why do some of my classnames come back as "<>c" with the new VS 2015 compilers?

我们有一堆 EF 迁移 类 在我们的集成测试中执行。对于一些测试,我们发现迁移 类 使用反射:

var dbMigrationClasses = migrationsAssembly.GetTypes()
                         .Where(t => t.IsSubclassOf(typeof(DbMigration)));

然后我们在一些测试中使用.Name 属性:

var migrationsWithInvalidClassNames = migrationClasses
                                      .Where(mt => !IsValidMigrationClassName(mt.Name));

但是,自从升级到 VS 2015 RC 后,我们的许多 类 报告他们的名字为“<>c”,全名也以此结尾:

Name = "<>c"
FullName = "DataMigrations.Migrations._20150121090200_DoSomeStuff+<>c"

这从来没有发生过(我猜是 VS 2015 的新编译器导致了它),而且它只发生在我们迁移的一些(可能四分之一)类 中。所有 类 似乎都相同(所有内部,相同 methods/attributes)。

我可以通过读取 FullName 并将其剥离来处理这个问题,但我很想知道发生了什么以及为什么它只影响某些 类。这里有两个例子 类,一个很好,一个是 <>c。我删除的只是其中的 SQL:

// File 1
namespace NewMind.DMS.DataMigrations.Migrations
{
    [MigrationName("Drop the SavedSearchJSON column from the SavedSearch table.")]
    internal class _20150121143400_DropTheSavedSearchJSONColumnFromTheSavedSearchTable : DmsMigration
    {
        public override void Up()
        {
            Sql(@"(SNIP)");
        }
    }
}

// File 2
namespace NewMind.DMS.DataMigrations.Migrations
{
    [MigrationName("Update Facility Key data type as it was incorrectly smallint in some databases.")]
    internal class _20150424130800_StandardiseFacilityKeyDataType : DmsMigration
    {
        public override void Up()
        {
            Sql(@"(SNIP)");
        }
    }
}

您不需要使用 FullName - _20150121090200_DoSomeStuff 部分只是 "parent" class。 <>c 嵌套在 _20150121090200_DoSomeStuff 中。因此,要获取嵌套 class 及其父项的名称,您可以这样做:

public static string GetAnonymousName(this Type type)
{
  if (!type.IsNested) return type.Name;

  return type.DeclaringType.GetAnonymousName() + "+" + type.Name;
}

我认为它在 VS2015 中没有改变。也许您使用的是 Entity Framework 或类似版本的更新版本?

好的,这是用户错误:

我实际上错过了代码中的重要一行...我们发现迁移 class 有两种方式...基础 class 和命名空间:

// Get all possible migration classes (use base class + namespace)
var dbMigrationClasses = migrationsAssembly.GetTypes().Where(t => t.IsSubclassOf(typeof(DbMigration)));
var migrationNamespaceClasses = migrationsAssembly.GetTypes().Where(t => t.Namespace != null && t.Namespace.EndsWith(".Migrations", StringComparison.OrdinalIgnoreCase));

// Join them together for tests to query
migrationClasses = dbMigrationClasses.Union(migrationNamespaceClasses);

这意味着除了 实际的 classes 之外,我们还从新编译器 中获取编译器生成的 classes。

为什么我在文件中没有发现任何差异?我误读了 class 名称,并在其旁边选择了类似的迁移。猜猜正确的是什么?...

AddColumn("SavedSearch", "SavedSearchXML", c => c.String(nullable: false, defaultValue: "", isMaxLength: true));

多哈