string是我们的朋友。我们离不开string,但是有时候string也挺烦人的。
比如说,下面的代码,根据方法名来获取MethodInfo:
var info
=
typeof
(DateTime).GetMethod(
"
ToShortDateSting
"
);
Console.WriteLine(info.Name);
Console.WriteLine(info.Name);
进行“Rename Method”重构时,重构工具是不会去对string进行重命名的。
我们不得不手动去一个一个改。如果漏了一个,我们也不能能当场知道,等到程序报错时就太晚了!
我们可以通过lambda表达式,来获取MethodInfo:
var info
=
Reflect.GetMethod
<
DateTime
>
(dt
=>
dt.ToShortDateString());
Console.WriteLine(info.Name);
Console.WriteLine(info.Name);
同样,我们可以获取PropertyInfo:
var dayProperty
=
Reflect.GetProperty
<
DateTime
>
(dt
=>
dt.Day);
Console.WriteLine(dayProperty.Name);
Console.WriteLine(dayProperty.Name);
下面是实现代码:
public
static
class
Reflect
{
public static MethodInfo GetMethod < TClass > (Expression < Action < TClass >> expression)
{
var methodCall = expression.Body as MethodCallExpression;
if (methodCall == null )
{
throw new ArgumentException( " Expected method call " );
}
return methodCall.Method;
}
public static PropertyInfo GetProperty < TClass > (Expression < Func < TClass, object >> expression)
{
MemberExpression memberExpression;
var unary = expression.Body as UnaryExpression;
if (unary != null )
{
memberExpression = unary.Operand as MemberExpression;
}
else
{
memberExpression = expression.Body as MemberExpression;
}
if (memberExpression == null || ! (memberExpression.Member is PropertyInfo))
{
throw new ArgumentException( " Expected property expression " );
}
return (PropertyInfo) memberExpression.Member;
}
}
{
public static MethodInfo GetMethod < TClass > (Expression < Action < TClass >> expression)
{
var methodCall = expression.Body as MethodCallExpression;
if (methodCall == null )
{
throw new ArgumentException( " Expected method call " );
}
return methodCall.Method;
}
public static PropertyInfo GetProperty < TClass > (Expression < Func < TClass, object >> expression)
{
MemberExpression memberExpression;
var unary = expression.Body as UnaryExpression;
if (unary != null )
{
memberExpression = unary.Operand as MemberExpression;
}
else
{
memberExpression = expression.Body as MemberExpression;
}
if (memberExpression == null || ! (memberExpression.Member is PropertyInfo))
{
throw new ArgumentException( " Expected property expression " );
}
return (PropertyInfo) memberExpression.Member;
}
}
更实用的例子是,MVC的RedirectToAction方法:
public
class
HomeController : Controller
{
public void Index()
{
if ( ! UserIsLoggedIn)
{
RedirectToAction( " Login " );
}
}
public void Login()
{
}
}
{
public void Index()
{
if ( ! UserIsLoggedIn)
{
RedirectToAction( " Login " );
}
}
public void Login()
{
}
}
用同样的方法,上面的代码,可以重写为:
public
class
HomeController : Controller
{
public void Index()
{
if ( ! UserIsLoggedIn)
{
this .RedirectToAction(c => c.Login());
}
}
}
}
{
public void Index()
{
if ( ! UserIsLoggedIn)
{
this .RedirectToAction(c => c.Login());
}
}
public void Login()
{}
}
下面是实现代码:
public
static
class
ControllerExtensions
{
public static void RedirectToAction < TController > ( this TController controller, Expression < Action < TController >> expression) where TController : Controller
{
var methodCall = expression.Body as MethodCallExpression;
if (methodCall == null )
{
throw new ArgumentException( " Expected method call " );
}
controller.RedirectToAction(methodCall.Method.Name);
}
}
{
public static void RedirectToAction < TController > ( this TController controller, Expression < Action < TController >> expression) where TController : Controller
{
var methodCall = expression.Body as MethodCallExpression;
if (methodCall == null )
{
throw new ArgumentException( " Expected method call " );
}
controller.RedirectToAction(methodCall.Method.Name);
}
}
参考:http://blog.andreloker.de/post/2008/06/Getting-rid-of-strings-%282%29-use-lambda-expressions.aspx
注意:个人意见,仅供参考!