Explaining Delegates in C# - Part 2 (Events 1)

本文介绍了使用 C# 创建事件的基本方法,遵循三个必须规则:定义带有两个参数的委托;参数代表发布者和事件信息对象;第二个对象必须从 EventArgs 派生。通过示例代码演示了如何创建和触发事件。

In my previous post, I spoke about a few very basic and simple reasons of using delegates - primarily callback. In this post, I'll talk about creating Events using delegates.

I have tried to annotate the class with comments so that it is easy to comprehend. But IMHO, the best way to figure out what's going on is to copy/paste the following code and create breakpoint in the Main() class and hit F11 to step into the code. You will notice that Events are based on the Observer or Publish/Subscribe design pattern.

There are 3 rules which are MANDATORY when you are planning to create events...

Rule 1> The delegate must be defined with two arguments
Rule 2> These arguments always represent TWO objects… 
            The Publisher (object that raised the event)
            Event Information object
Rule 3> The 2nd object HAS to be derived from EventArgs

Step through the code and see for yourself how easy this is!!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegatesAndEvents
{
    //There are 3 rules which are MANDATORY when you are planning to create events
    //Rule 1> The delegate must be defined with two arguments
    //Rule 2> These arguments always represent TWO objects… 
    //          The Publisher (object that raised the event)
    //          Event Information object
    //Rule 3> The 2nd object HAS to be derived from EventArgs

    //To comply with Rule 3 we create a LoggerEventArgs which is derived from EventArgs
    class LoggerEventArgs : EventArgs
    {
        //constructor to initialize the UserName property
        public LoggerEventArgs(string UserName)
        {
            this.username = UserName;
        }

        string username;
        public string UserName
        {
            get { return username; }
        }
    };

    //To comply with Rule 1 and 2, in the publisher class we created a delegate and event declaration
    class InventoryManager // Publisher
    {
        public delegate void LoggerEventHandler(object source, LoggerEventArgs e);
        public event LoggerEventHandler OnInventoryUpdate;

        //This method will fire an event called OnInventoryUpdate whenever called
        public void LogEvent(string username)
        {
            LoggerEventArgs e = new LoggerEventArgs(username);
            if (OnInventoryUpdate != null)
            {
                Console.WriteLine("LogEvent > Raising events to all subscribers...\n");
                OnInventoryUpdate(this, e);
            }
        }
    };

    class InventoryLogger // Subscriber
    {
        InventoryManager inventoryManager;
        public InventoryLogger(InventoryManager inventoryManager)
        {
            Console.WriteLine("InventoryWatcher > Subscribing to OnInventoryUpdate event...\n");
            this.inventoryManager = inventoryManager;

            //Wiring the event so that the event is fired
            inventoryManager.OnInventoryUpdate += 
                    new InventoryManager.LoggerEventHandler(OnInventoryUpdate);
        }

        void OnInventoryUpdate(object source, LoggerEventArgs e)
        {
            Console.WriteLine("The guy who changed this inventory was... " + e.UserName);
        }
    }

    class DelegateEvents
    {
        public static void Main()
        {
            InventoryManager inventoryManager = new InventoryManager();

            Console.WriteLine("Main > Instantiating the subscriber... \n\n");
            InventoryLogger inventoryLog = new InventoryLogger(inventoryManager);

            inventoryManager.LogEvent("Rahul Soni");
            Console.ReadLine();
        }
    };
}

In the next post, I will talk about Asynchronous callbacks using delegates.

 

转: http://www.dotnetscraps.com/dotnetscraps/post/Explaining-Delegates-in-C-Part-2-(Events).aspx

05-15
### C2F-EMA Algorithm Implementation and Explanation The term **C2F-EMA** does not appear directly within the provided references, but based on its structure, it can likely stand for an algorithmic concept involving exponential moving averages (EMA) applied to a specific domain such as clustering or optimization problems. Below is an attempt at explaining what this might represent in the broader IT context. #### Hypothetical Definition of C2F-EMA In many computational contexts, especially those dealing with time-series data analysis, signal processing, or even machine learning models like K-means clustering[^3], EMA (Exponential Moving Average) plays a critical role due to its ability to smooth out short-term fluctuations while highlighting long-term trends. A possible interpretation of **C2F-EMA** could involve: 1. **Clustering-based Exponential Moving Average**: This suggests applying EMAs during iterative processes where clusters are refined over multiple iterations. 2. **Customized Two-Factor Weighting Scheme**: The prefix "C2F-" may imply that two factors—such as distance metrics between points and centroids—are weighted dynamically using an exponentially decaying factor. This approach aligns well with concepts from approximation algorithms[^1] since maintaining approximate solutions through adaptive weights ensures convergence without excessive computation costs. #### Potential Pseudocode Example Below demonstrates how one might implement a simplified version of a hypothetical `C2F-EMA` function tailored towards improving cluster assignments iteratively by leveraging exponential smoothing techniques. ```python import numpy as np def c2f_ema(data_points, initial_centroids, alpha=0.9): """ Custom Clustering via Exponentially-weighted Moving Averages Parameters: data_points (list): List of input vectors representing dataset entries. initial_centroids (list): Initial guesses for centroid positions. alpha (float): Smoothing parameter controlling weight decay rate [^4]. Returns: final_clusters (dict): Mapping each point index to assigned cluster ID after iteration completes. """ n_iter = 50 # Number of refinement steps allowed before stopping early exit condition met tol = 1e-6 # Tolerance threshold indicating negligible change across consecutive updates prev_loss = float('inf') current_centroids = np.array(initial_centroids) for _ in range(n_iter): distances = [] labels = [] # Compute pairwise Euclidean distances & assign closest label per sample for pt_idx, p in enumerate(data_points): dist_to_all_centers = [ ((p - center)**2).sum()**(1/2.) for center in current_centroids] min_dist_loc = int(np.argmin(dist_to_all_centers)) distances.append(min_dist_loc) labels.append((pt_idx,min_dist_loc)) updated_positions = {i:[np.zeros_like(current_centroids[i])]for i,_ in enumerate(current_centroids)} counts_per_group={} total_sq_error=sum([d*d for d,lbl in zip(*labels)]) if abs(prev_loss-total_sq_error)<tol*total_sq_error: break prev_loss=total_sq_error # Update new centers according to formula incorporating previous value w/smoothness controlled via 'alpha' for idx,(point,label_) in enumerate(labels): try: updated_positions[label_] += [(1-alpha)*current_centroids[label_]+alpha*np.asarray(point)] except KeyError: pass next_gen_cents=[updated_pos[-1]/len(updated_pos)if len(updated_pos)>0 else orig_center \ for label_,(orig_center,*updated_pos)in sorted([(k,v)for k,v in updated_positions.items()],key=lambda x:x[0]) ] current_centroids=np.stack(next_gen_cents,axis=-1).T return dict(zip(range(len(data_points)),distances)) # Sample Usage Scenario X = [[1.,2],[8.,7],[-3,-4]] init_guesses=[[0,0],[5,5]] result=c2f_ema(X, init_guesses,alpha=.8)[^5] print(result) ``` Here we define a custom routine which incorporates ideas similar to traditional methods yet introduces novel aspects inspired potentially by descriptions found earlier regarding approximations schemes used alongside other numerical procedures mentioned previously throughout your query inputs.[^6]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值