C# 类A的静态方法不是从类B的静态构造函数调用的
我有以下课程C# 类A的静态方法不是从类B的静态构造函数调用的,c#,oop,C#,Oop,我有以下课程 public class A { protected static Dictionary<string,Func<BaseClass>> dict = new Dictionary<string,Func<BaseClass>>(); public static void AddGenerator(string type,Func<BaseClass> fncCreate
public class A
{
protected static Dictionary<string,Func<BaseClass>> dict = new Dictionary<string,Func<BaseClass>>();
public static void AddGenerator(string type,Func<BaseClass> fncCreateObject)
{
dict.Add(type,fncCreateObject);
}
}
class B : BaseClass
{
static B()
{
A.AddGenerator("b",CreateObject);
}
protected B()
{}
pulic static B CreateObject()
{
return new B();
}
}
公共A类
{
受保护的静态字典dict=新字典();
公共静态void AddGenerator(字符串类型,Func fncCreateObject)
{
dict.Add(类型,fncCreateObject);
}
}
B类:基本类
{
静态B()
{
A.AddGenerator(“b”,CreateObject);
}
受保护的B()
{}
脉冲静态B CreateObject()
{
返回新的B();
}
}
注意:上面的代码只是一个示例,但与我试图实现的目标密切相关
很多人会建议使用IoC容器,比如NInject或Unity,但我写这篇文章的主要原因是想弄清楚为什么上面的代码没有按预期执行
因此,在上面的代码中,我希望类B的静态构造函数调用类A的静态方法,并且在应用程序生命周期的其余部分,字典中应该有一个条目可用
然而,当我运行代码并调试时,我发现字典是空的
为什么从类B的静态构造函数调用的代码没有执行?来自:
在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类
显然,在检查字典的代码中,还没有创建任何实例,也没有引用任何静态成员。来自:
在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类
显然,在您检查字典的代码中,还没有创建任何实例,也没有引用任何静态成员。不完全是将示例转换为MEF的1:1,但它应该能让您很好地了解MEF的功能:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(".");
var compositeCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
var container = new CompositionContainer(compositeCatalog);
var a = A.Instance;
container.SatisfyImportsOnce(a);
a.PrintCatalog();
}
}
public sealed class A
{
private static readonly A instance = new A();
static A() { }
private A() { }
public static A Instance { get { return instance; } }
[ImportMany]
private List<IBType> BTypes;
public void PrintCatalog()
{
foreach (var bType in BTypes)
{
Console.WriteLine(bType.GetType());
}
}
}
[Export(typeof(IBType))]
class B:IBType
{
static B()
{
}
protected B()
{}
public void DoSomething() { }
}
[Export(typeof(IBType))]
class B2:IBType
{
static B2()
{
}
protected B2()
{}
public void DoSomething() { }
}
interface IBType
{
void DoSomething();
}
}
使用系统;
使用System.Collections.Generic;
命名空间控制台应用程序4
{
使用System.ComponentModel.Composition;
使用System.ComponentModel.Composition.Hosting;
运用系统反思;
班级计划
{
静态void Main(字符串[]参数)
{
var assemblyCatalog=新的assemblyCatalog(Assembly.getExecutionGassembly());
var directoryCatalog=新的directoryCatalog(“.”);
var compositeCatalog=新聚合Catalog(assemblyCatalog,directoryCatalog);
var container=新的合成容器(compositeCatalog);
var a=a.实例;
集装箱。满足进口要求(a);
a、 PrintCatalog();
}
}
公众密封A类
{
私有静态只读A实例=新A();
静态A(){}
私有A(){}
公共静态实例{get{return Instance;}}
[进口数量]
私有列表b类型;
public void PrintCatalog()
{
foreach(BTypes中的var bType)
{
WriteLine(bType.GetType());
}
}
}
[导出(typeof(IBType))]
B类:IBType
{
静态B()
{
}
受保护的B()
{}
公共void DoSomething(){}
}
[导出(typeof(IBType))]
B2类:IBType
{
静态B2()
{
}
受保护的B2()
{}
公共void DoSomething(){}
}
接口IBType
{
无效剂量();
}
}
我还包括了我所知的最安全的单例模式实现。MEF将允许您在运行时动态解析同一接口的许多实现。我也用过,比如版本和名字。
但是,如果您需要它来处理基本抽象类,请查看
与上面的代码相同,但具有元数据属性,请使用示例:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var directoryCatalog = new DirectoryCatalog(".");
var compositeCatalog = new AggregateCatalog(assemblyCatalog, directoryCatalog);
var container = new CompositionContainer(compositeCatalog);
var a = A.Instance;
container.SatisfyImportsOnce(a);
a.PrintCatalog();
a.BTypes.Single(s=>s.Metadata.Name.Equals("Second")).Value.DoSomething();
}
}
public sealed class A
{
private static readonly A instance = new A();
static A() { }
private A() { }
public static A Instance { get { return instance; } }
[ImportMany]
public List<Lazy<IBType,IBTypeMetadata>> BTypes;
public void PrintCatalog()
{
foreach (var bType in BTypes)
{
Console.WriteLine(bType.Value.GetType());
}
}
}
[Export(typeof(IBType))]
[BTypeMetadata("First")]
class B:IBType
{
static B()
{
}
protected B()
{}
public void DoSomething() { }
}
[Export(typeof(IBType))]
[BTypeMetadata("Second")]
class B2 : IBType
{
static B2()
{
}
protected B2()
{}
public void DoSomething()
{
Console.WriteLine("Hello from Second");
}
}
public interface IBType
{
void DoSomething();
}
public interface IBTypeMetadata
{
string Name { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class BTypeMetadataAttribute : ExportAttribute
{
public string Name { get; set; }
public BTypeMetadataAttribute(string name)
: base(typeof(IBTypeMetadata)) { Name = name; }
}
}
使用系统;
使用System.Collections.Generic;
命名空间控制台应用程序4
{
使用System.ComponentModel.Composition;
使用System.ComponentModel.Composition.Hosting;
使用System.Linq;
运用系统反思;
班级计划
{
静态void Main(字符串[]参数)
{
var assemblyCatalog=新的assemblyCatalog(Assembly.getExecutionGassembly());
var directoryCatalog=新的directoryCatalog(“.”);
var compositeCatalog=新聚合Catalog(assemblyCatalog,directoryCatalog);
var container=新的合成容器(compositeCatalog);
var a=a.实例;
集装箱。满足进口要求(a);
a、 PrintCatalog();
a、 BTypes.Single(s=>s.Metadata.Name.Equals(“Second”)).Value.DoSomething();
}
}
公众密封A类
{
私有静态只读A实例=新A();
静态A(){}
私有A(){}
公共静态实例{get{return Instance;}}
[进口数量]
公共列表b类型;
public void PrintCatalog()
{
foreach(BTypes中的var bType)
{
WriteLine(bType.Value.GetType());
}
}
}
[导出(typeof(IBType))]
[BTypeMetadata(“第一”)]
B类:IBType
{
静态B()
{
}
受保护的B()
{}
公共void DoSomething(){}
}
[导出(typeof(IBType))]
[B类型元数据(“第二”)]
B2类:IBType
{
静态B2()
{
}
受保护的B2()
{}
公共无效剂量测定法()
{
Console.WriteLine(“你好,第二位”);
}
}
公共接口IBType
{
无效剂量();
}
公共接口IBTypeMetadata
{
字符串名称{get;}
}
[元数据属性]
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false)]
公共类BTypeMetadataA