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>
,后者又继承自 DbContext
。 DbContext
包含采用单个字符串的构造函数。
您所指的 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
在我的 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>
,后者又继承自 DbContext
。 DbContext
包含采用单个字符串的构造函数。
您所指的 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