如何在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