C# 什么';使用或不使用委托的区别是什么

C# 什么';使用或不使用委托的区别是什么,c#,delegates,C#,Delegates,我对理解使用委托的概念有些怀疑,下面是我的委托示例 本例使用照片过滤软件作为实例,它将向照片添加过滤器,使用委托将增加将来添加新过滤器的灵活性 使用委托前 Photo.cs: class Photo { private string path; public Photo(string path) { this.path = path; Console.WriteLine("{0} impo

我对理解使用委托的概念有些怀疑,下面是我的委托示例

本例使用照片过滤软件作为实例,它将向照片添加过滤器,使用委托将增加将来添加新过滤器的灵活性

使用委托前

Photo.cs:

 class Photo
    {
        private string path;

        public Photo(string path)
        {
            this.path = path;
            Console.WriteLine("{0} imported", path);
        }

        public void Save()
        {
            Console.WriteLine("{0} photo saved", this.path);
        }
    }
PhotoFilter.cs:

class PhotoFilter
{
    public void AddBrigtness(Photo photo)
    {
        Console.WriteLine("Added Brightness");
    }

    public void AddFilter(Photo photo)
    {
        Console.WriteLine("Added Filter");
    }

    public void AddShadow(Photo photo)
    {
        Console.WriteLine("Added Shadow");
    }
}
PhotoProcesser.cs:

class PhotoProcesser
{
   public void Process(string path)
    {
        var photo = new Photo(path);
        var filter = new PhotoFilter();

        filter.AddBrigtness(photo);
        filter.AddFilter(photo);
        filter.AddShadow(photo);

        photo.Save();
    }
}
 delegate void PhotoMethodHandler(Photo p); // Delegate

    class PhotoProcesser
    {
       public void Process(string path,PhotoMethodHandler methodHandler)
        {
            var photo = new Photo(path);

            methodHandler(photo);

            photo.Save();
        }
    }
Program.cs:

class Program
{
    static void Main(string[] args)
    {
        var process = new PhotoProcesser();
        process.Process("123.jpg");
    }
}
  class Program
    {
        static void Main(string[] args)
        {
            var filter = new PhotoFilter();

            PhotoMethodHandler p = filter.AddBrigtness;
            p += filter.AddFilter;
            p += RemoveRedEyeFilter; // To simulate the flexibility of using Delegate

            var process = new PhotoProcesser();
            process.Process("123.jpg",p);
        }

        static void RemoveRedEyeFilter(Photo photo) // Newly added filter
        {
            Console.WriteLine("Added RemoveRedEye");
        }
    }
  class Program
    {    
        static void Main(string[] args)
        {
            var photo = new Photo("p1.jpg");
            var filter = new PhotoFilter();

            filter.AddBrigtness(photo);
            filter.AddFilter(photo);
            RemoveRedEyeFilter(photo);

            photo.Save();

        }

        static void RemoveRedEyeFilter(Photo photo) // Newly added filter
        {
            Console.WriteLine("Added RemoveRedEye");
        }
    } 
使用委托后

***Photo.cs和PhotoFilter.cs保持不变

PhotoProcesser.cs:

class PhotoProcesser
{
   public void Process(string path)
    {
        var photo = new Photo(path);
        var filter = new PhotoFilter();

        filter.AddBrigtness(photo);
        filter.AddFilter(photo);
        filter.AddShadow(photo);

        photo.Save();
    }
}
 delegate void PhotoMethodHandler(Photo p); // Delegate

    class PhotoProcesser
    {
       public void Process(string path,PhotoMethodHandler methodHandler)
        {
            var photo = new Photo(path);

            methodHandler(photo);

            photo.Save();
        }
    }
Program.cs:

class Program
{
    static void Main(string[] args)
    {
        var process = new PhotoProcesser();
        process.Process("123.jpg");
    }
}
  class Program
    {
        static void Main(string[] args)
        {
            var filter = new PhotoFilter();

            PhotoMethodHandler p = filter.AddBrigtness;
            p += filter.AddFilter;
            p += RemoveRedEyeFilter; // To simulate the flexibility of using Delegate

            var process = new PhotoProcesser();
            process.Process("123.jpg",p);
        }

        static void RemoveRedEyeFilter(Photo photo) // Newly added filter
        {
            Console.WriteLine("Added RemoveRedEye");
        }
    }
  class Program
    {    
        static void Main(string[] args)
        {
            var photo = new Photo("p1.jpg");
            var filter = new PhotoFilter();

            filter.AddBrigtness(photo);
            filter.AddFilter(photo);
            RemoveRedEyeFilter(photo);

            photo.Save();

        }

        static void RemoveRedEyeFilter(Photo photo) // Newly added filter
        {
            Console.WriteLine("Added RemoveRedEye");
        }
    } 
输出:

此时,我可以理解将委托用作函数指针的灵活性, 但是如果我们用另一种方式思考,如果我们不使用PhotoProcesser.cs并按以下方式更改Program.cs,我们也可以得到相同的结果:

Program.cs:

class Program
{
    static void Main(string[] args)
    {
        var process = new PhotoProcesser();
        process.Process("123.jpg");
    }
}
  class Program
    {
        static void Main(string[] args)
        {
            var filter = new PhotoFilter();

            PhotoMethodHandler p = filter.AddBrigtness;
            p += filter.AddFilter;
            p += RemoveRedEyeFilter; // To simulate the flexibility of using Delegate

            var process = new PhotoProcesser();
            process.Process("123.jpg",p);
        }

        static void RemoveRedEyeFilter(Photo photo) // Newly added filter
        {
            Console.WriteLine("Added RemoveRedEye");
        }
    }
  class Program
    {    
        static void Main(string[] args)
        {
            var photo = new Photo("p1.jpg");
            var filter = new PhotoFilter();

            filter.AddBrigtness(photo);
            filter.AddFilter(photo);
            RemoveRedEyeFilter(photo);

            photo.Save();

        }

        static void RemoveRedEyeFilter(Photo photo) // Newly added filter
        {
            Console.WriteLine("Added RemoveRedEye");
        }
    } 
输出:

它将获得与使用委托相同的结果和灵活性(在本例中添加新过滤器)

根据上面的例子,谁能给我一些指导,让我了解使用委派的好处/不同之处?谢谢

委托背后的思想(以及使用lambda或任何指向函数的指针)是能够将静态行为(由代码定义)转换为动态行为(由数据定义)

例如,我可以做:

Photo p = new Photo();
p = ApplyX(p);
p = ApplyY(p);
...
但有了代理,我可以做到

List<Func<Photo,Photo>> filters = Whatever();
Photo p = new Photo();
foreach(var filter in filters)
{
   p = filter(p);
}
List filters=Whatever();
照片p=新照片();
foreach(过滤器中的var过滤器)
{
p=过滤器(p);
}
这将允许您在运行时更改过滤器列表(通过在过滤器列表中插入和删除委托)


您可以检查以下内容以进一步阅读:

这可能会对您有所帮助:EventHandler是委托的子级,因此情况有所不同。根据这个例子,我很困惑何时以及为什么我应该使用委托?在可重用性方面,如果我们需要多次处理相同的操作,使用委托可以减少一些代码。我说得对吗?