假如在项目中,有多个方法,他们的开头和结尾都是差不多的,不变的只是中间的那部分逻辑。比如:

1
2
3
4
5
6
7
8
9
10
11
12
static 
void 
f1()
        
{
            
Console.WriteLine(
"begin"
);
            
Console.WriteLine(
"do something1!"
);
            
Console.WriteLine(
"end"
);
        
}
        
static 
void 
f2()
        
{
            
Console.WriteLine(
"begin"
);
            
Console.WriteLine(
"do something2!"
);
            
Console.WriteLine(
"end"
);
        
}

常规调用的话,写法为

1
2
f1();
f2();

那么如何复用公共部分呢?可以使用委托来实现。设计一个公共类,含有一个公有静态方法:

1
2
3
4
5
6
7
8
9
class 
Common
    
{
        
public 
static 
void 
f(Action action)
        
{
            
Console.WriteLine(
"begin"
);
            
action();
            
Console.WriteLine(
"end"
);
        
}
    
}

那么,调用的时候,只需要如下实现即可:

1
2
Common.f(() => Console.WriteLine(
"do something 1111!"
));
Common.f(() => Console.WriteLine(
"do something 2222!"
));

上述中,对于f1(),f2()方法的提取,有一个前提,就是f1(),f2()的输入参数是相同的(此处没有输入参数)。只有在这种输入参数一致的情况下,才能够用这种方法抽取出来。

那么对于任意输入参数的方法,如何提取公共部分呢?

一种方法是对公共的方法实现多个泛型参数的重载:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class 
Common
    
{
      
public 
static 
void 
f(Action action)
        
{
            
Console.WriteLine(
"begin"
);
            
action();
            
Console.WriteLine(
"end"
);
        
}
        
public 
static 
void 
f<T1>(Action<T1> action,T1 arg1)
        
{
            
Console.WriteLine(
"begin"
);
            
action(arg1);
            
Console.WriteLine(
"end"
);
        
}
        
public 
static 
void 
f<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
        
{
            
Console.WriteLine(
"begin"
);
            
action(arg1, arg2);
            
Console.WriteLine(
"end"
);
        
}
  
}

根据实际需要,可以重载多个方法。这样的话,调用的时候也很方便。

假设如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
static 
void 
f1(
int 
i)
        
{
            
Console.WriteLine(
"begin"
);
            
Console.WriteLine(i);
            
Console.WriteLine(
"end"
);
        
}
        
static 
void 
f2(
int 
i, 
string 
s)
        
{
            
Console.WriteLine(
"begin"
);
            
Console.WriteLine(i); Console.WriteLine(s);
            
Console.WriteLine(
"end"
);
        
}

输入参数是不同的。那么通过上面的方法抽取后,只需要如下写法就可以了。

1
2
Common.f<
int
>((i) => Console.WriteLine(i), 3);
Common.f<
int
string
>((i, s) => { Console.WriteLine(i); Console.WriteLine(s); }, 3, 
"www"
);

还有一种方法是使用Delegate类。

实现如下:

1
2
3
4
5
6
public 
static 
void 
f(Delegate exp, 
params 
dynamic[] d)
      
{
          
Console.WriteLine(
"begin"
);
          
exp.DynamicInvoke(d);
          
Console.WriteLine(
"end"
);
      
}

代码中,使用Delegate类,通过DynamicInvoke方法实现对委托的调用。该方法更为简单。调用的时候只需要如下方式的代码即可:

1
2
3
4
Action<
int
> p = (a) => Console.WriteLine(a);
Action<
int
string
> p2 = (a, s) => { Console.WriteLine(a); Console.WriteLine(s); };
Common.f(p, 3);
Common.f(p2, 3,
"ww"
);

注意:Delegate 类 (Delegate class)并不是delegate类型(delegate type).Delegate class是用来获取delegate type的一个类。可以认为delegate type是Delegate class的一个实例。

本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1205719
,如需转载请自行联系原作者