扩展方法是.net3.5以后出现的一个比较优雅的写法,昨天讨论中有同学提出这也是通过反射实现的,不过我并不这么认为。
扩展方法的定义必须是静态类的静态方法,对一个静态类的静态方法进行反射明显不明智。而且linq to object中大量使用扩展方法,如果是用发射实现方法调用,明显过于笨拙。
那么事实到底如何
先定义一个扩展方法和一个同样功能的非扩展方法
public static class StringHelp
{
/// <summary>
/// 裁减字符串(扩展方法写法)
/// </summary>
/// <param name="source"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string CutStr(this string source, int length, string lastString)
{
if (string.IsNullOrEmpty(source))
return "";
if (source.Length > length)
{
string result = string.Empty;
source.ToCharArray().Take(length).ToList().ForEach(p => { result += p.ToString(); });
return result + lastString;
}
else
return source;
}
/// <summary>
/// 裁减字符串(非扩展方法写法)
/// </summary>
/// <param name="source"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string CutStrNew(string source, int length, string lastString)
{
if (string.IsNullOrEmpty(source))
return "";
if (source.Length > length)
{
string result = string.Empty;
source.ToCharArray().Take(length).ToList().ForEach(p => { result += p.ToString(); });
return result + lastString;
}
else
return source;
}
}
{
/// <summary>
/// 裁减字符串(扩展方法写法)
/// </summary>
/// <param name="source"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string CutStr(this string source, int length, string lastString)
{
if (string.IsNullOrEmpty(source))
return "";
if (source.Length > length)
{
string result = string.Empty;
source.ToCharArray().Take(length).ToList().ForEach(p => { result += p.ToString(); });
return result + lastString;
}
else
return source;
}
/// <summary>
/// 裁减字符串(非扩展方法写法)
/// </summary>
/// <param name="source"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string CutStrNew(string source, int length, string lastString)
{
if (string.IsNullOrEmpty(source))
return "";
if (source.Length > length)
{
string result = string.Empty;
source.ToCharArray().Take(length).ToList().ForEach(p => { result += p.ToString(); });
return result + lastString;
}
else
return source;
}
}
然后分别进行扩展方法调用,静态方法调用,反射调用三种调用
class Program
{
static void Main(string[] args)
{
string str = "hello world!";
Stopwatch watch = new Stopwatch();
Console.WriteLine(str.CutStr(5, "..."));
Console.WriteLine(StringHelp.StringHelp.CutStrNew(str, 5, "..."));
Console.WriteLine(typeof(StringHelp.StringHelp).GetMethod("CutStr").Invoke(null, new object[] { str, 5, "..." }));
//效率比较
watch.Start();
for (int i = 0; i < 100000; i++)
{
str.CutStr(5, "...");
}
watch.Stop();
Console.WriteLine("1:"+watch.ElapsedMilliseconds);
watch.Restart();
for (int i = 0; i < 100000; i++)
{
StringHelp.StringHelp.CutStrNew(str, 5, "...");
}
watch.Stop();
Console.WriteLine("2:" + watch.ElapsedMilliseconds);
watch.Restart();
for (int i = 0; i < 100000; i++)
{
typeof(StringHelp.StringHelp).GetMethod("CutStr").Invoke(null, new object[] { str, 5, "..." });
}
watch.Stop();
Console.WriteLine("3:" + watch.ElapsedMilliseconds);
Console.Read();
}
}
{
static void Main(string[] args)
{
string str = "hello world!";
Stopwatch watch = new Stopwatch();
Console.WriteLine(str.CutStr(5, "..."));
Console.WriteLine(StringHelp.StringHelp.CutStrNew(str, 5, "..."));
Console.WriteLine(typeof(StringHelp.StringHelp).GetMethod("CutStr").Invoke(null, new object[] { str, 5, "..." }));
//效率比较
watch.Start();
for (int i = 0; i < 100000; i++)
{
str.CutStr(5, "...");
}
watch.Stop();
Console.WriteLine("1:"+watch.ElapsedMilliseconds);
watch.Restart();
for (int i = 0; i < 100000; i++)
{
StringHelp.StringHelp.CutStrNew(str, 5, "...");
}
watch.Stop();
Console.WriteLine("2:" + watch.ElapsedMilliseconds);
watch.Restart();
for (int i = 0; i < 100000; i++)
{
typeof(StringHelp.StringHelp).GetMethod("CutStr").Invoke(null, new object[] { str, 5, "..." });
}
watch.Stop();
Console.WriteLine("3:" + watch.ElapsedMilliseconds);
Console.Read();
}
}