在不破坏当前分配的情况下将方法分配给私有委托
Assign method to private delegate without breaking the current assignment
我想使用一些 class 的私有委托,但不会中断当前的分配。
我能以某种方式确保我的更改(通过反射完成)不会断开 WriteToDebug 吗?
委托是私有的,"Inform"是私有的
public class ExternalClass
{
private delegate void InformDelegate(string info);//PRIVATE!
private InformDelegate Inform { get; set; }//PRIVATE!
public ExternalClass()
{
Inform = WriteToDebug;//Default method
}
public void Foo(string bar)
{
Inform?.Invoke(bar);
}
private void WriteToDebug(string info)
{
Debug.WriteLine($"Info: {info}");
}
}
将我的方法添加到委托和一些测试(需要Debug.WriteLine + MessageBox.Show)
public class MyClass
{
public void Test(string message)
{
ExternalClass externalClass = new ExternalClass();
externalClass.Foo(message);
//Assign MyMethod to SomeClass.Inform
MethodInfo mi = GetType().GetMethod(nameof(MyMethod), BindingFlags.NonPublic | BindingFlags.Instance);
PropertyInfo pi = externalClass.GetType().GetProperty("Inform", BindingFlags.NonPublic | BindingFlags.Instance);
object del = Delegate.CreateDelegate(pi.PropertyType, this, mi);
Type type = externalClass.GetType().GetNestedType("Inform", BindingFlags.Public | BindingFlags.NonPublic);
pi.SetValue(externalClass, del);
//Try Foo again
externalClass.Foo(message);//TODO: Ensure that the call "Inform? .Invoke (bar);" triggered both methods: WriteToDebug and MyMethod.
}
private void MyMethod(string msg)
{
MessageBox.Show(msg);
}
}
验证
internal class Program
{
private static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Test("Hello Word!");
Console.ReadKey();
}
}
我会很感激你的帮助
您必须通过 Delegate.Combine.
将您的代表与现有代表(此处:指向 WriteToDebug
)合并
通过以下方式检索这个已经存在的:
Delegate original = pi.GetValue(externalClass) as Delegate;
并通过以下方式合并您的新版本:
Delegate combined = Delegate.Combine(original, del);
注意,传入委托的顺序代表执行顺序。
上面的完整代码如下所示。
ExternalClass externalClass = new ExternalClass();
MethodInfo mi = GetType().GetMethod(nameof(MyMethod), BindingFlags.NonPublic | BindingFlags.Instance);
PropertyInfo pi = externalClass.GetType().GetProperty("Inform", BindingFlags.NonPublic | BindingFlags.Instance);
Delegate del = Delegate.CreateDelegate(pi.PropertyType, this, mi);
Delegate original = pi.GetValue(externalClass) as Delegate;
Delegate combined = Delegate.Combine(original, del);
pi.SetValue(externalClass, combined);
externalClass.Foo(message);
我想使用一些 class 的私有委托,但不会中断当前的分配。 我能以某种方式确保我的更改(通过反射完成)不会断开 WriteToDebug 吗?
委托是私有的,"Inform"是私有的
public class ExternalClass
{
private delegate void InformDelegate(string info);//PRIVATE!
private InformDelegate Inform { get; set; }//PRIVATE!
public ExternalClass()
{
Inform = WriteToDebug;//Default method
}
public void Foo(string bar)
{
Inform?.Invoke(bar);
}
private void WriteToDebug(string info)
{
Debug.WriteLine($"Info: {info}");
}
}
将我的方法添加到委托和一些测试(需要Debug.WriteLine + MessageBox.Show)
public class MyClass
{
public void Test(string message)
{
ExternalClass externalClass = new ExternalClass();
externalClass.Foo(message);
//Assign MyMethod to SomeClass.Inform
MethodInfo mi = GetType().GetMethod(nameof(MyMethod), BindingFlags.NonPublic | BindingFlags.Instance);
PropertyInfo pi = externalClass.GetType().GetProperty("Inform", BindingFlags.NonPublic | BindingFlags.Instance);
object del = Delegate.CreateDelegate(pi.PropertyType, this, mi);
Type type = externalClass.GetType().GetNestedType("Inform", BindingFlags.Public | BindingFlags.NonPublic);
pi.SetValue(externalClass, del);
//Try Foo again
externalClass.Foo(message);//TODO: Ensure that the call "Inform? .Invoke (bar);" triggered both methods: WriteToDebug and MyMethod.
}
private void MyMethod(string msg)
{
MessageBox.Show(msg);
}
}
验证
internal class Program
{
private static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Test("Hello Word!");
Console.ReadKey();
}
}
我会很感激你的帮助
您必须通过 Delegate.Combine.
将您的代表与现有代表(此处:指向WriteToDebug
)合并
通过以下方式检索这个已经存在的:
Delegate original = pi.GetValue(externalClass) as Delegate;
并通过以下方式合并您的新版本:
Delegate combined = Delegate.Combine(original, del);
注意,传入委托的顺序代表执行顺序。
上面的完整代码如下所示。
ExternalClass externalClass = new ExternalClass();
MethodInfo mi = GetType().GetMethod(nameof(MyMethod), BindingFlags.NonPublic | BindingFlags.Instance);
PropertyInfo pi = externalClass.GetType().GetProperty("Inform", BindingFlags.NonPublic | BindingFlags.Instance);
Delegate del = Delegate.CreateDelegate(pi.PropertyType, this, mi);
Delegate original = pi.GetValue(externalClass) as Delegate;
Delegate combined = Delegate.Combine(original, del);
pi.SetValue(externalClass, combined);
externalClass.Foo(message);