.Net生成通用方法 [英] .Net generate generic methods

查看:99
本文介绍了.Net生成通用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆我想订阅的通用事件,并使它们都调用一个非泛型方法。这里是我的代码:

  public delegate void PropertyChangedDelegate< OwnerType,PropertyType>(OwnerType sender,PropertyType oldValue,PropertyType newValue); 

公共类EventObject
{
公共事件PropertyChangedDelegate< Object,Boolean>的PropertyChanged;
公共事件PropertyChangedDelegate< Object,Int32> XChanged;


static void Main()
{
EventObject eventObject = new EventObject();
EventInfo eventInfo = eventObject.GetType()。GetEvent(PropertyChanged);
eventInfo.AddEventHandler(eventObject,PropertyChanged);


static void PropertyChanged(Object obj,Object oldValue,Object newValue)
{
}

显然这不起作用,有什么办法可以做一个包装器的泛型方法?

解决方案

问题在于 PropertyChanged 方法与 PropertyChangedDelegate 类型不矛盾,因为发送 bool 作为 object 需要装箱,所以很显然你不能让委托与所有事件通用。解决方法是编写一个静态方法作为着陆方法。这是我的解决方案:使用System;

  
使用System.Reflection;

public delegate void PropertyChangedDelegate< OwnerType,PropertyType>(OwnerType sender,PropertyType oldValue,PropertyType newValue);

公共类EventObject
{
公共事件PropertyChangedDelegate< Object,Boolean>的PropertyChanged;
公共事件PropertyChangedDelegate< Object,Int32> XChanged;

public void RaisePropertyChanged(){
PropertyChanged(this,true,false); (








EventObject eventObject = new EventObject() ;
EventInfo eventInfo = eventObject.GetType()。GetEvent(PropertyChanged);
键入evType = eventInfo.EventHandlerType;
//在实例方法
的情况下,用this.GetType()替换下面的类型type typeType = typeof(Test);
MethodInfo mi = thisType.GetMethod(PropertyChanged,BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
MethodInfo genericMi = mi.MakeGenericMethod(evType.GetGenericArguments());
Delegate del = Delegate.CreateDelegate(evType,genericMi);
eventInfo.AddEventHandler(eventObject,del);
//测试
eventObject.RaisePropertyChanged();

$ b static void PropertyChanged< TOwner,T>(TOwner obj,T oldValue,T newValue)
{
Console.WriteLine( - Invoked - );


$ / code>

灵感来源于

使用反射来获取带参数的静态方法





使用反射创建泛型委托


I have a bunch of generic events I want to subscribe to and make them all call one non-generic method. Here's my code:

public delegate void PropertyChangedDelegate<OwnerType, PropertyType>(OwnerType sender, PropertyType oldValue, PropertyType newValue);

public class EventObject
{
    public event PropertyChangedDelegate<Object, Boolean> PropertyChanged;
                public event PropertyChangedDelegate<Object, Int32> XChanged;
}

static void Main()
{
    EventObject eventObject = new EventObject();
    EventInfo eventInfo = eventObject.GetType().GetEvent("PropertyChanged");
    eventInfo.AddEventHandler(eventObject, PropertyChanged);
}

    static void PropertyChanged(Object obj, Object oldValue, Object newValue)
    {
    }

Obviously this doesn't work, is there any way to do a wrapper generic method?

解决方案

The issue is that PropertyChanged method is not contravariant to the PropertyChangedDelegate type because sending bool as object require boxing, so it is clear that you cannot make delegate to work universally with all events. The solution is to write a static method as a "landing method". Here is my solution:

using System;
using System.Reflection;

public delegate void PropertyChangedDelegate<OwnerType, PropertyType>(OwnerType sender, PropertyType oldValue, PropertyType newValue);

public class EventObject
{
    public event PropertyChangedDelegate<Object, Boolean> PropertyChanged;
    public event PropertyChangedDelegate<Object, Int32> XChanged;

    public void RaisePropertyChanged() {
        PropertyChanged(this, true, false);
    }
}

class Test {

    static void Main()
    {
        EventObject eventObject = new EventObject();
        EventInfo eventInfo = eventObject.GetType().GetEvent("PropertyChanged"); 
        Type evType = eventInfo.EventHandlerType;
        // replace below with this.GetType() in case of instance method
        Type thisType = typeof(Test); 
        MethodInfo mi = thisType.GetMethod("PropertyChanged", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
        MethodInfo genericMi = mi.MakeGenericMethod(evType.GetGenericArguments());
        Delegate del = Delegate.CreateDelegate(evType, genericMi);
        eventInfo.AddEventHandler(eventObject, del);
        // Test
        eventObject.RaisePropertyChanged();
    }

    static void PropertyChanged<TOwner, T>(TOwner obj, T oldValue, T newValue)
    {
        Console.WriteLine("-- Invoked --");
    }
}

Inspired from

Using Reflection to get static method with its parameters

and

Create generic delegate using reflection

这篇关于.Net生成通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆