繁体   English   中英

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

[英]How to declare generic event for generic delegate in c#

我有一个用户控件来处理fileupload。 我已经定义了一个委托如下

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

value可以是字符串也可以是字节数组。 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 FileUploadSuccess<T> successString. 

除了作为通用类型的一部分(即

class Foo<T> { public event SomeEventType<T> SomeEventName; }

)没有泛型属性,字段,事件,索引器或运算符(只有泛型类型和泛型方法)。 这里的包含类型可以是通用的吗?

对外界来说,一个事件在很多方面看起来像是一个阶级的领域。 就像您不能使用开放泛型类型来声明字段一样,您不能使用开放泛型类型来声明事件。

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

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

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

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

但这只会将您的问题移到另一个位置,因为现在您必须声明FileUploader类的两个实例:

FileUploader<string> stringUploader = new FileUploader<string>();
FileUploader<byte[]> stringUploader = new FileUploader<byte[]>();

这可能不是你想要的。

为什么需要通用事件? 你不能只使用正常的事件:

public delegate void FileUploadSuccess(object value);

然后

public event FileUploadSuccess Success;

在Success事件处理程序中,您将知道要传递的对象的类型:

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

我不认为这是可能的。

事件就像一个委托的实例(粗略地讲),一个实例是一个具体的实现(泛型或非泛型类)。

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

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

来源: https//docs.microsoft.com/en-us/dotnet/api/system.eventhandler-1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM