How to declare generic event for generic delegate in c#

后端 未结 6 1986
不思量自难忘°
不思量自难忘° 2020-12-17 16:55

I have a user control which deals with fileupload. I have defined a delegate as follows

public delegate void FileUploadSuccess(T value,FileUploadTyp         


        
相关标签:
6条回答
  • 2020-12-17 17:21

    That's impossible unless you define your type parameter in an enclosing class. For example:

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

    But this only moves your problem to another location, since now you would have to declare two instances of the FileUploader class:

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

    This may not be what you want.

    0 讨论(0)
  • 2020-12-17 17:31

    I don't think this is possible.

    Event is like an instance of a delegate (roughly speaking), and an instance is a concrete implementation ( of a generic or a non-generic class).

    For better understanding of delegates and event, you can refer to this SO discussion.

    0 讨论(0)
  • 2020-12-17 17:34

    Why do you need a generic event? Can't you just use a normal event:

    public delegate void FileUploadSuccess(object value);
    

    and then

    public event FileUploadSuccess Success;
    

    In the Success event handler you will know the type of the object being passed:

    public void SuccessHandler(object value)
    {
        // you know the type of the value being passed here
    }
    
    0 讨论(0)
  • 2020-12-17 17:35

    To the outside world, an event in many ways looks like a field of the class. Just as you can't use an open generic type to declare a field, you can't use an open generic type to declare an event.

    If you could leave the type open, then the compiler would have to compile in the event handler add and remove code for every possible type for your generic parameter T. A closed generic type can't be JIT compiled, because your event is not a type in its own right, rather is a part of an enclosing type.

    0 讨论(0)
  • 2020-12-17 17:37

    Except as part of generic types (i.e.

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

    ) there is no such thing as generic properties, fields, events, indexers or operators (only generic types and generic methods). Can the containing type here be generic?

    0 讨论(0)
  • 2020-12-17 17:44

    There is a generic EventHandler class in the .Net Framework just for this purpose:

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

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

    0 讨论(0)
提交回复
热议问题