Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# 如何在c中为泛型委托声明泛型事件#_C#_.net - Fatal编程技术网

C# 如何在c中为泛型委托声明泛型事件#

C# 如何在c中为泛型委托声明泛型事件#,c#,.net,C#,.net,我有一个处理文件上传的用户控件。我对委托的定义如下 public delegate void FileUploadSuccess<T>(T value,FileUploadType F) public委托void FileUploadSuccess(T值,FileUploadType F) 值可以是字符串,也可以是字节数组。FileUploadType是一个枚举,它告诉您上载了哪种类型的文件 现在,我在usercontrol中声明了一个事件来引发这个问题 public event

我有一个处理文件上传的用户控件。我对委托的定义如下

public delegate void FileUploadSuccess<T>(T value,FileUploadType F)
public委托void FileUploadSuccess(T值,FileUploadType F)
值可以是字符串,也可以是字节数组。FileUploadType是一个枚举,它告诉您上载了哪种类型的文件

现在,我在usercontrol中声明了一个事件来引发这个问题

public event FileUploadSuccess<string> successString;   //In case I want a file name

public event FileUploadSuccess<Byte[]> successStringImage;  // In case I want a byte[] of uploaded image
public event fileuploadsuccessstring//以防我需要一个文件名
公共事件文件上载成功successStringImage;//如果我想要上传图像的字节[]
我想要的是一个普通的活动

public event FileUploadSuccess<T> successString. 
public event FileUploadSuccess successString。

在外界看来,事件在许多方面都像是类的字段。正如不能使用开放泛型类型来声明字段一样,也不能使用开放泛型类型来声明事件


如果您可以让类型保持打开状态,那么编译器必须在事件处理程序中编译,为泛型参数
T
添加和删除每种可能类型的代码。封闭泛型类型不能进行JIT编译,因为您的事件本身不是类型,而是封闭类型的一部分。

我认为这是不可能的

事件类似于委托的实例(粗略地说),而实例是具体的实现(泛型或非泛型类)


为了更好地理解代表和事件,您可以参考讨论。

除非作为泛型类型的一部分(即

class Foo{public event SomeEventType SomeEventName;}

)没有泛型属性、字段、事件、索引器或运算符(只有泛型类型和泛型方法)。此处包含的类型是否为泛型?

除非在封闭类中定义类型参数,否则这是不可能的。例如:

public delegate void FileUploadSuccess<T>(T value, FileUploadType F)

public class FileUploader<T>
{
    public event FileUploadSuccess<T> FileUploaded;
}

这可能不是您想要的。

为什么需要一般事件?您不能只使用普通事件:

public delegate void FileUploadSuccess(object value);
然后

public event FileUploadSuccess Success;
在成功事件处理程序中,您将知道要传递的对象的类型:

public void SuccessHandler(object value)
{
    // you know the type of the value being passed here
}

.Net Framework中有一个通用EventHandler类,仅用于此目的:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Counter c = new Counter(new Random().Next(10));
            c.ThresholdReached += c_ThresholdReached;

            Console.WriteLine("press 'a' key to increase total");
            while (Console.ReadKey(true).KeyChar == 'a')
            {
                Console.WriteLine("adding one");
                c.Add(1);
            }
        }

        static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
        {
            Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold,  e.TimeReached);
            Environment.Exit(0);
        }
    }

    class Counter
    {
        private int threshold;
        private int total;

        public Counter(int passedThreshold)
        {
            threshold = passedThreshold;
        }

        public void Add(int x)
        {
            total += x;
            if (total >= threshold)
            {
                ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
                args.Threshold = threshold;
                args.TimeReached = DateTime.Now;
                OnThresholdReached(args);
            }
        }

        protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
        {
            EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
    }

    public class ThresholdReachedEventArgs : EventArgs
    {
        public int Threshold { get; set; }
        public DateTime TimeReached { get; set; }
    }
}
使用系统;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
计数器c=新计数器(new Random().Next(10));
c、 ThresholdReach+=c_ThresholdReach;
Console.WriteLine(“按“a”键增加总数”);
while(Console.ReadKey(true).KeyChar=='a')
{
Console.WriteLine(“添加一条”);
c、 增加(1);
}
}
静态无效c_ThresholdReach(对象发送方,ThresholdReach事件参数e)
{
WriteLine(“在{1}处达到了{0}的阈值。”,e.threshold,e.timereach);
环境。退出(0);
}
}
班级计数器
{
私有整数阈值;
私人整数合计;
公共计数器(整数通过阈值)
{
阈值=超过阈值;
}
公共无效添加(int x)
{
总数+=x;
如果(总数>=阈值)
{
ThresholdReachedEventArgs args=新的ThresholdReachedEventArgs();
args.Threshold=阈值;
args.timereach=DateTime.Now;
达到OnThreshold(args);
}
}
ResholdReach上受保护的虚拟无效(ThresholdReacheEventArgs e)
{
EventHandler=ThresholdReached;
if(处理程序!=null)
{
处理者(本,e);
}
}
已达到公共事件事件处理程序阈值;
}
公共类阈值ReacheEventArgs:EventArgs
{
公共整数阈值{get;set;}
公共日期时间到达时间{get;set;}
}
}

来源:

先生,我想让它成为类型安全的,我想如果泛型可以帮上忙的话。
public void SuccessHandler(object value)
{
    // you know the type of the value being passed here
}
using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Counter c = new Counter(new Random().Next(10));
            c.ThresholdReached += c_ThresholdReached;

            Console.WriteLine("press 'a' key to increase total");
            while (Console.ReadKey(true).KeyChar == 'a')
            {
                Console.WriteLine("adding one");
                c.Add(1);
            }
        }

        static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
        {
            Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold,  e.TimeReached);
            Environment.Exit(0);
        }
    }

    class Counter
    {
        private int threshold;
        private int total;

        public Counter(int passedThreshold)
        {
            threshold = passedThreshold;
        }

        public void Add(int x)
        {
            total += x;
            if (total >= threshold)
            {
                ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
                args.Threshold = threshold;
                args.TimeReached = DateTime.Now;
                OnThresholdReached(args);
            }
        }

        protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
        {
            EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
    }

    public class ThresholdReachedEventArgs : EventArgs
    {
        public int Threshold { get; set; }
        public DateTime TimeReached { get; set; }
    }
}