chr*_*ris 79 c# parameters asp.net-mvc
看一下HtmlHelpers的一些代码示例,我看到的声明如下:
public static string HelperName(this HtmlHelper htmlHelper, ...more regular params )
Run Code Online (Sandbox Code Playgroud)
我不记得在其他地方看到过这种类型的构造 - 有人可以解释"这个"的目的吗?我认为通过声明一些公共静态意味着该类不需要实例化 - 所以在这种情况下什么是"this"?
ang*_*son 196
这是声明扩展方法的语法,扩展方法是C#3.0的一个新特性.
扩展方法是部分代码,部分编译器"魔术",其中编译器在Visual Studio中使用intellisense使得看起来您的扩展方法实际上可用作相关对象的实例方法.
让我举个例子.
String类上没有名为GobbleGobble的方法,所以让我们创建一个扩展方法:
public static class StringExtensions
{
public static void GobbleGobble(this string s)
{
Console.Out.WriteLine("Gobble Gobble, " + s);
}
}
Run Code Online (Sandbox Code Playgroud)
类名只是我的命名约定,没有必要像这样命名,但它必须是静态的,方法也是如此.
声明上述方法后,您可以在Visual Studio中键入以下内容:
String s = "Turkey Baster!";
s.
Run Code Online (Sandbox Code Playgroud)
在点之后,等待intellisense,并注意到那里有一个GobbleGobble方法,完成如下代码:
String s = "Turkey Baster!";
s.GobbleGobble();
Run Code Online (Sandbox Code Playgroud)
要点:声明扩展方法的类必须可供编译器和智能感知处理器使用,以便intellisense显示该方法.如果您手动输入GobbleGobble并使用Ctrl+ .快捷键,则无法帮助您在文件中使用指令.
请注意,方法的参数已消失.编译器将默默地移动重要位,这些位是:
String s = "Turkey Baster!";
s.GobbleGobble();
^ ^
| +-- the compiler will find this in the StringExtensions class
|
+-- will be used as the first parameter to the method
Run Code Online (Sandbox Code Playgroud)
因此,上面的代码将由编译器转换为:
String s = "Turkey Baster!";
StringExtensions.GobbleGobble(s);
Run Code Online (Sandbox Code Playgroud)
所以在通话时,它并没有什么神奇之处,它只是对静态方法的调用.
请注意,如果您的扩展方法声明了多个参数,则只有第一个支持this
修饰符,其余的必须作为方法调用的一部分指定为正常:
public static void GobbleGobble(this string value, string extra)
{ | |
... | |
} | |
| |
+--------------------------------------------+ |
| |
v |
s.GobbleGobble("extra goes here"); |
^ |
| |
+-----------------------------------+
Run Code Online (Sandbox Code Playgroud)
扩展方法部分归因于Linq,其中C#的Linq语法将为正在使用的对象寻找适当命名的扩展方法,这意味着只需声明正确的扩展即可将Linq-support"引入"任何类型的类中方法.当然,完整的Linq支持是很多工作,但它是可能的.
此外,扩展方法本身非常有用,所以请阅读它.
这里有几个链接:
在扩展方法之后,我一直在疯狂地使用它们.这里有一些我经常使用的..
public static T ChangeType<T>(this object obj)
{
return (T)Convert.ChangeType(obj, typeof(T));
}
Run Code Online (Sandbox Code Playgroud)
像这样工作..
int i = "123".ChangeType<int>();
bool valid = "bool".ChangeType<bool>();
int id = dataSet.Tables[0].Rows[0]["Id"].ChangeType<int>();
Run Code Online (Sandbox Code Playgroud)
是的,它显示在每个单独的对象上,可能很烦人,但由于我几乎每种数据类型都使用它,因此只需将对象附加到对象而不是为每种可能的数据类型复制它.
public static string ToXml(this object serializableObject)
{
var aMemStr = new MemoryStream();
try
{
var serializer = new XmlSerializer(serializableObject.GetType());
serializer.Serialize(new XmlTextWriter(aMemStr, null), serializableObject);
return Encoding.UTF8.GetString(aMemStr.ToArray());
}
finally { if (aMemStr != null) { aMemStr.Dispose(); } }
}
string xml = dataSet.ToXml();
public static T ToObject<T>(this string xmlString)
{
var aStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));
try { return (T)new XmlSerializer(typeof(T)).Deserialize(aStream); }
finally { if (aStream != null) { aStream.Dispose(); aStream = null; } }
}
DataSet dataSet = xml.ToObject<DataSet>();
Run Code Online (Sandbox Code Playgroud)
它用于扩展方法.基本上你将Helpername"粘合"到htmlHelper对象,这样你就可以说:
new HtmlHelper().HelperName(...more regular params);
Run Code Online (Sandbox Code Playgroud)
那将是一个扩展方法。它们允许您通过位于原始类之外的静态方法“扩展”一个类。
例如,假设您有一个一直在使用的有用字符串方法......
public int CountAllAs(string orig)
{
return orig.ToLowerInvariant().ToArray().Count(c => c == 'a');
}
Run Code Online (Sandbox Code Playgroud)
而你称之为...
string allAs = "aaaA";
int count = CountAllAs(allAs);
Run Code Online (Sandbox Code Playgroud)
这还不错。但是只要稍作改动,您就可以将其设置为 Extension 方法,并且调用会更漂亮一点:
public static int CountAllAs(this string orig)
{
return orig.ToLowerInvariant().ToArray().Count(c => c == 'a');
}
Run Code Online (Sandbox Code Playgroud)
然后叫它...
string allAs = "aaaA";
int count = allAs.CountAllAs();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
35022 次 |
最近记录: |