通过反射重新实例化静态构造函数



>我使用第三方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(( 任何关于它是否可能或可能是一些替代方案的问题

谢谢

最简单的方法是将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(如上所示(。

尝试重新运行静态构造函数,如下所示:

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;
}

另请参阅如何使用反射调用静态构造函数?

但是 2 失败,第三个只知道构造函数已经运行。

最新更新