替代if esle 的高级方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
if else 是入门最常遇到的一种结构,这种结构简单易懂,深受初学者喜爱。但是 If-Else通常是一个糟糕的选择。
它的可读性差,如果用的太多,会导致结构重构困难。今天我就介绍替代 If-Else的方法。
一、字典重构,完全不用If-Else
 
下面是我们最常见的 If-Else实现
string type = "B";
            if (type=="A")
            {
                Console.WriteLine("执行A");
            }
            else if (type=="B")
            {
                Console.WriteLine("执行B");
            }
            else if(type=="C")
            {
                Console.WriteLine("执行C");
            }
 
可能很多人会喜欢这种方式,可是对于拓展来说,体验并不好。后面如果再增加操作的话,可以考虑重构成字典。
 Dictionary<string, Action> ActionDao = new Dictionary<string, Action>();
            ActionDao.Add("A", () => { Console.WriteLine("执行A"); });
            ActionDao.Add("B", () => { Console.WriteLine("执行B"); });
            ActionDao.Add("C", () => { Console.WriteLine("执行C"); });
 
            ActionDao[type].Invoke();
 
我们把ifelse 重构成Key-Value的模式,执行Action完成需要处理的事情。这种拓展大大的方便阅读和拓展的需要。
二、策略模式,完全不用If-Else
除了这个,我们还可以使用策略模式去实现。不过,策略模式的代码会比较复杂。
1、首先我们需要抽象一个方法出来
 public interface IToDao
    {
        string Show(string val);
    }
2、实现接口
 public class AToDao : IToDao
    {
        public string Show(string val)
        {
            Console.WriteLine(val);
            return val;
        }
    }
     
      public class BToDao : IToDao
    {
        public string Show(string val)
        {
            Console.WriteLine(val);
            return val;
        }
    }
     
       public class CToDao : IToDao
    {
        public string Show(string val)
        {
            Console.WriteLine(val);
            return val;
        }
    }
3、创建一个特性,这个特性的目的是获取标记实现了抽象接口的实例化
    
   public class DisPlayAttribute:System.Attribute
    {
 
        public string Name;
        public DisPlayAttribute(string name)
        {
            Name=name;
        }
        public string DisPlayShow()
        {
            
            return Name;
        }
    }
4、然后我们给实现了接口的类都加上特性
 [DisPlayAttribute("AToDao")]
    public class AToDao : IToDao
    {
        public string Show(string val)
        {
            Console.WriteLine("策略模式执行A:"+val);
            return val;
        }
    }
    [DisPlayAttribute("BToDao")]
    public class BToDao : IToDao
    {
        public string Show(string val)
        {
            Console.WriteLine("策略模式执行B:"+val);
            return val;
        }
    }
    [DisPlayAttribute("CToDao")]
    public class CToDao : IToDao
    {
        public string Show(string val)
        {
            Console.WriteLine("策略模式执行C:"+val);
            return val;
        }
    }
5、接下来我们就可以通过特性获取到对应的类进行实例化,调用接口方法了,代码如下:
     private void ShowMsg(string intype)
        {
            Dictionary<string,Type> keyValuePairs= Assembly.GetEntryAssembly()
                .GetExportedTypes()//获取全部的type
                .Where(ty=>ty.GetInterfaces().Contains(typeof( IToDao)))//获取 继承了 IToDao 类
 
                .ToDictionary(ty=>ty.GetCustomAttribute<DisPlayAttribute>().DisPlayShow());//获取 继承了 IToDao 类 通过特性获取类名称
 
            Type type= keyValuePairs[intype];//获取 type
            //Type type = Type.GetType(assemblyName + "." + intype);
 
            // 创建类型的一个实例
            IToDao toDao =  Activator.CreateInstance(type) as IToDao;//获取 type 实例化接口
            if (toDao != null)
            {
                toDao.Show(intype);
            }
        }
 
总结:简单的逻辑使用IFELSE不影响,但是如果后面还需要拓展,可以使用更高级的写法!字典模式相对简单,也比较容易读懂。我自己也比较喜欢。策略模式优势是拓展性好,但是代码阅读起来会比较困难。因为不知道是哪个地方实现的。可以根据需求,选择不同的实现方式。
参考文档:
https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/attributes/accessing-attributes-by-using-reflection

  


__EOF__

本文作者one996
本文链接https://www.cnblogs.com/one966/p/16986167.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   一半春风  阅读(201)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示