C#调用baseclass构造函数混淆

C# calling base class constructor confusion

在我的 asp.net MVC 应用程序中,我使用 entity framework 和 Identity 进行用户身份验证。所以我的 DbContext class 看起来像下面这样(有效):

public class PropertyContext : IdentityDbContext<AppUser>
    {
        public PropertyContext() : base("name=PropertyBDConnection") { }
         ...
    }

我正在将一个字符串传递给 PropertyContext 的基本构造函数。因此,我可以假设 IdentityDbContext 有一个将字符串作为参数的构造函数。

但是在 asp.net 身份 (here IdentityDbContext.cs) 的 github 存储库中,我发现了以下内容-

public class IdentityDbContext<TUser> : 
      IdentityDbContext<TUser, IdentityRole, string> 
      where TUser : IdentityUser
{ }

根本没有构造函数。当然是我遗漏了什么或者找错地方了。

是的,您找错地方了:根据文档,IdentityDbContext has three constructors,其中一个需要 string:

  • IdentityDbContext()
  • IdentityDbContext(DbConnection, DbCompiledModel, Boolean)
  • IdentityDbContext(String)

IdentityDbContext<TUser> 继承自 IdentityDbContext<TUser, IdentityRole, string>,后者又继承自 DbContextDbContext 包含采用单个字符串的构造函数。

您所指的 IdentityDBContext class 继承自另一个 class IdentityDbContext<TUser, TRole, TKey>,后者又继承自 DbContext。看上面参考文件的第29行IdentityDbContext.cs

我实际上没有访问源代码的权限,但我想指出 C# 的一个棘手功能,即隐式运算符:https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx

由于 IdentityDBContext 在您的 linked 源代码中有一个采用 DBContextOptions 的构造函数,因此 class 可以使用隐式转换器将字符串从字符串转换为 DBContextOptions

这里为您做了一个片段来解释它是如何工作的,它模拟了一种可能的方式来实现您所看到的,这并不意味着实际就是这种情况,可能您只是指向了错误的代码库,但这是可能的

using System;
public class Program {
    public class IdentityDbContext {
        public DbContextOptions Options { get; set; }
        public IdentityDbContext(DbContextOptions options){
            this.Options = options;
        }
    }

    public class DbContextOptions {
        public string Config { get; set; }

        public DbContextOptions(string config){
            this.Config = config;
        }

        public static implicit operator DbContextOptions(string config) {
            return new DbContextOptions(config);
        }
    }

    public static void Main()
    {
        IdentityDbContext f = new IdentityDbContext(new DbContextOptions("test")); //it's ok
        Console.WriteLine(f.Options.Config);

        IdentityDbContext f2 = new IdentityDbContext("testWithImplicit");
        Console.WriteLine(f2.Options.Config);
    }
}

更新: 添加了一个 fiddle link: https://dotnetfiddle.net/aykOqq