在一个类中声明一个静态方法并将它用作另一个类的方法
我正在为ASP.NET MVC做Nerd Dinner tutorial,我遇到了一种C#语言的构造,这看起来很奇怪。这个问题的标题有点含糊,因为我很难定义这是什么。这也使我很难搜索这个话题,因此我决定提出一个问题。在一个类中声明一个静态方法并将它用作另一个类的方法
在Nerd Dinner tutorial我看到下面的代码片段:
public static class ControllerHelpers {
public static void AddRuleViolations(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors) {
foreach (RuleViolation issue in errors) {
modelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
}
}
后来他们表明:
//
// GET: /Dinners/Edit/2
public ActionResult Edit(int id) {
Dinner dinner = dinnerRepository.GetDinner(id);
return View(dinner);
}
//
// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {
Dinner dinner = dinnerRepository.GetDinner(id);
try {
UpdateModel(dinner);
dinnerRepository.Save();
return RedirectToAction("Details", new { id=dinner.DinnerID });
}
catch {
ModelState.AddRuleViolations(dinner.GetRuleViolations());
return View(dinner);
}
}
让我困惑的部分是:
public static void AddRuleViolations(this ModelStateDictionary modelState, IEnumerable<RuleViolation> errors)
和
ModelState.AddRuleViolations(dinner.GetRuleViolations());
看起来您在ControllerHelpers
类中定义AddRuleViolations
函数,然后像调用ModelState
属性的实例函数那样调用它。这个观察是否正确?如果是,为什么你需要这个?我觉得在一个类中定义一个方法就好像它是另一个类的方法一样。
注意:ModelState
是当前类的属性,而不是它自己的类。
这是因为它是extension method。这就是“this”位在第一个参数的开始处。
扩展方法的思想是,它们允许您有效地将功能添加到现有的类。所以,如果您有:
public static class StringExtensions
{
public static string Reverse(this string text)
{
char[] chars = text.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
}
那么你可以这样调用:
string x = "hello world";
string y = x.Reverse();
,如果你会写,实际上被编译:
string x = "hello world";
string y = StringExtensions.Reverse(x);
扩展方法必须是在顶级非泛型静态类中声明。他们在LINQ中大量使用。
那个观察确实是正确的;这是一个扩展方法,由参数型前this
修改说明:
this ModelStateDictionary modelState
然后,编译器将解决的方法寻找像ModelStateDictionary
实例方法调用,但要注意它仍然是实际上一个静态调用 - 这样:
obj.SomeStaticMethod(arg1, arg2);
是实际上编译为:
TheDeclaringType.SomeStaticMethod(obj, arg1, arg2);
这可能会导致古怪如obj
可以null
和电话仍然可以工作。
感谢您的回答。所以如果我调用'obj.SomeStaticMethod',并且'obj'为'null',并且在函数内部执行'obj = new Object()'。而且是否可以用值类型来做到这一点? – 2010-11-18 14:08:02
'Matthijs'你可以在方法*中给它一个值*,但该参数不是'ref'(并且不能),所以它将**从不**显示回*方法外部。 'structs'不能为空('Nullable
啊谢谢。如果没有扩展方法关键字,我找不到任何关于它的内容。 – 2010-11-18 14:06:42