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

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

public delegate void FileUploadSuccess(T value,FileUploadType F) 

value可以是字符串以及字节数组。 FileUploadType是一个枚举,它告诉上载了哪种类型的文件。

现在我在usercontrol中声明了一个事件来提高它。

 public event FileUploadSuccess successString; //In case I want a file name public event FileUploadSuccess successStringImage; // In case I want a byte[] of uploaded image 

我想要的是一般事件

 public event FileUploadSuccess successString. 

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

 class Foo { public event SomeEventType SomeEventName; } 

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

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

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

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

 public delegate void FileUploadSuccess(T value, FileUploadType F) public class FileUploader { public event FileUploadSuccess FileUploaded; } 

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

 FileUploader stringUploader = new FileUploader(); FileUploader stringUploader = new FileUploader(); 

这可能不是你想要的。

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

 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 } 

我不认为这是可能的。

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

为了更好地理解代表和事件,您可以参考此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 handler = ThresholdReached; if (handler != null) { handler(this, e); } } public event EventHandler 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