我正在使用第三方dll进行某些操作,该类的实例是静态的,并且有时会崩溃。 我在想是否有办法通过反射来重新初始化课程。
我使用DotPeek来检查库,它看起来像这样:
public class C_SomeWrapper
{
private static C_SomeWrapper _instance;
public C_SomeWrapper()
{
InitStuff();
}
void InitStuff()
{
}
public void Destroy()
{
C_SomeWrapper._instance = (C_SomeWrapper)null;
}
public static C_SomeWrapper Instanse
{
get
{
if (C_SomeWrapper._instance == null)
C_SomeWrapper._instance = new C_SomeWrapper();
return C_SomeWrapper._instance;
}
}
}
当我提到它时:
C_SomeWrapper _wrapper=C_SomeWrapper.Instanse
由于崩溃,我想Destroy()并重新实例化构造函数。
我当时认为可以访问_instance
并通过反射使其为空。
我想提一下,仅Destroy()不起作用,所以可能我需要调用构造函数并调用InitStuff()
关于是否可行或可能有其他选择的任何疑惑
谢谢
答案 0 :(得分:1)
最简单的方法是将C_SomeWrapper._instance
重设为null,然后让现有代码为您重新创建实例。下面的示例做到了这一点(尽管它使用了不同的类名和字段名)。
我正在使用一种名为MyPrivateClass
的类型,该类型包含一个名为SomeField
的可为空的静态字段(这是我一直在徘徊的一个类):
var myType = typeof(MyPrivateClass);
var anObject = new MyPrivateClass();
var myField = myType.GetField("SomeField", BindingFlags.Static | BindingFlags.NonPublic);
myField.SetValue(anObject, null);
最后,私有字段anObject.SomeField
为空。
我不确定这对于声明为static
的类如何工作。但是,看来FieldInfo.SetValue(null, null)
适用于静态成员。结果,您无需实例化anObject
(如上所示)。
答案 1 :(得分:0)
尝试像这样重新运行静态构造函数:
void Main()
{
var t = typeof(AmStaticHearMeRoar);
TryIt(t,RunConstructor);
TryIt(t,RunTypeInitializer);
TryIt(t, RunClassConstructor);
}
static void TryIt(Type t, Action<Type> f){
Console.WriteLine("value is:" + AmStaticHearMeRoar.State);
AmStaticHearMeRoar.Reset();
try{
f(t);
Console.WriteLine("constructor rerun, value is:" + AmStaticHearMeRoar.State);
} catch(Exception ex){
ex.Dump();
Console.WriteLine("constructor rerun?, value is:" + AmStaticHearMeRoar.State);
}
finally{
AmStaticHearMeRoar.Reset();
}
}
static void RunConstructor(Type t) {
var m = t.GetConstructor(BindingFlags.Static | BindingFlags.NonPublic, System.Type.DefaultBinder, System.Type.EmptyTypes, null);
m.Dump();
m.Invoke(new object[] {});
}
static void RunTypeInitializer(Type t){
t.TypeInitializer.Invoke(BindingFlags.NonPublic | BindingFlags.Static, System.Type.DefaultBinder, new object[] {},System.Globalization.CultureInfo.DefaultThreadCurrentCulture);
}
static void RunClassConstructor(Type t) {
// only works if it hasn't been run =(
RuntimeHelpers.RunClassConstructor(t.TypeHandle);
}
// Define other methods and classes here
public static class AmStaticHearMeRoar
{
static int myStaticState;
static AmStaticHearMeRoar()
{
myStaticState = 3;
}
public static void Reset() {
myStaticState = 0;
}
public static int State => myStaticState;
}
另请参阅How do I invoke a static constructor with reflection?
无论2失败了,第3个都知道构造函数已经运行。