Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何访问';s作为参数传入C中的泛型函数#_C#_Generics - Fatal编程技术网

C# 如何访问';s作为参数传入C中的泛型函数#

C# 如何访问';s作为参数传入C中的泛型函数#,c#,generics,C#,Generics,我有一个泛型方法,它有一些泛型类型的参数。我想做的是,能够在我的函数中访问这个泛型类型参数的方法 public void dispatchEvent<T>(T handler, EventArgs evt) { T temp = handler; // make a copy to be more thread-safe if (temp != null) {

我有一个泛型方法,它有一些泛型类型的参数。我想做的是,能够在我的函数中访问这个泛型类型参数的方法

    public void dispatchEvent<T>(T handler, EventArgs evt)
        {
            T temp = handler; // make a copy to be more thread-safe
            if (temp != null)
            {
                temp.Invoke(this, evt);
            }
        }
public void dispatchEvent(T处理程序,EventArgs evt)
{
T temp=handler;//创建一个更安全的副本
如果(温度!=null)
{
临时调用(本,evt);
}
}
我希望能够在temp上调用Invoke方法,temp类型为T。有什么方法可以做到这一点吗


谢谢。

对泛型使用约束:

public void dispatchEvent<T>(T handler, EventArgs evt) where T : yourtype
public void dispatchEvent(T handler,EventArgs evt),其中T:yourtype
这个怎么样:

    public void dispatchEvent<T>(T handler, EventArgs evt)
    {
        T temp = handler; // make a copy to be more thread-safe
        if (temp != null && temp is Delegate)
        {
            (temp as Delegate).Method.Invoke((temp as Delegate).Target, new Object[] { this, evt });
        }
    }
public void dispatchEvent(T处理程序,EventArgs evt)
{
T temp=handler;//创建一个更安全的副本
如果(temp!=null&&temp为委托)
{
(temp作为委托).Method.Invoke((temp作为委托).Target,新对象[]{this,evt});
}
}

您可能想要的东西更像:

        public void dispatchEvent<T>(EventHandler<T> handler, T evt) 
            where T: EventArgs
        {
            if (handler != null)
                handler(this, evt);
        }
public void dispatchEvent(EventHandler,T evt)
其中T:EventArgs
{
if(处理程序!=null)
处理程序(本,evt);
}
为了好玩,这里将其作为一种扩展方法:

    public static void Raise<T>(this EventHandler<T> handler, Object sender, T args)
        where T : EventArgs
    {
        if (handler != null)
            handler(sender, args);
    }
publicstaticvoidraise(此EventHandler、objectsender、T args)
其中T:EventArgs
{
if(处理程序!=null)
处理程序(发送方,args);
}

在那里创建副本不会使任何东西更线程安全。它将是一个引用类型,副本将是浅层的,并且您调用的对象将作用于完全相同的对象。这使它具有线程安全性,因为赋值和检查避免了处理程序引用更改时可能出现的问题(设置为null或其他地方的新赋值)在null测试和Invoke方法调用之间。@AMissico:
handler
无法在测试和Invoke调用之间更改。它是一个局部变量,并且已经包含引用的副本!除非我弄错了,这是可能的,但我很确定您所做的只是传递指向引用类型的指针。所以,若处理程序改变,temp也会改变,因为它们都只是指向一个对象。原因是引用类型是通过引用传递的。这意味着您的方法只接收到在何处查找对象的引用。希望这是正确的和有意义的。@dtb我认为这可能是错误的,但让我们等待,看看是否有人纠正我。但是值类型是作为克隆传递的,所以在这种情况下,您所说的是正确的。但对于引用类型,它们基本上只是指向对象的指针。因此,当您将一个指针传入一个方法时,只需将指针传递给该对象。所以,当你在这个方法中复制了一个类似的东西时,你只是在复制指针。他们都指向同一件事。但让我看看是否能找到一些东西来证实这一点。@dtb,谢谢,错过了。在我处理本地副本的时候去掉了它,因为它在本例中毫无意义(已经在参数中复制了)。是的,这就成功了。不知道扩展方法是什么@didibus:看一看,我不确定扩展方法是否适用于
事件
成员。