C#扩展方法只与类的一个实例一起工作。任何方式呢?
据我所知,C#才让我们使用扩展方法有一个类的实例:C#扩展方法只与类的一个实例一起工作。任何方式呢?
public class MyClass
{
public static string GetStuff()
{
return string.Empty;
}
}
public static class MyClassExtension
{
public static string GetOtherStuff(this MyClass myClass)
{
return string.Empty;
}
}
用法:
MyClass.GetStuff();
MyClass.GetOtherStuff(); // Cannot resolve symbol 'GetOtherStuff'
new MyClass().GetOtherStuff(); // This works
然而,我注意到,MVC框架允许我向HtmlHelpers以这种方式可以使用我的扩展方法而不创建任何类的实例。例如,如果我为HtmlHelper
这样创建一个扩展方法:
public static string MyHtmlHelper(this HtmlHelper helper)
{
return string.Empty;
}
我可以在Razor视图使用这样的:
@Html.MyHtmlHelper() // no need to instantiate a class
我真的想达到同样的结果我MyClass
,所以我可以这样做:
MyClass.GetOtherStuff()
我该怎么做?
您无法通过扩展方法向类添加静态方法...
因为它没有任何意义。你提出的建议与用你的新辅助方法创建第二个静态类没有什么不同。只要做到这一点。
你想这样做:
public class MyClass
{
public static string GetStuff()
{
return string.Empty;
}
// Extension method.
public static string GetOtherStuff()
{
// cannot use any non-public members of MyClass
return string.Empty;
}
}
MyClass.GetStuff();
MyClass.GetOtherStuff();
以上是不可能的。此外,它会给你没有优势只是在做:
public class MyClass
{
public static string GetStuff()
{
return string.Empty;
}
}
public class MyClassExtension
{
public static string GetOtherStuff()
{
// also cannot use any non-public members of MyClass
return string.Empty;
}
}
MyClass.GetStuff();
MyClassExtension.GetOtherStuff();
最后一个替代方案是创建一个子类:
public class MyClass
{
public static string GetStuff()
{
return string.Empty;
}
}
public class MyClassExtension : MyClass
{
public static string GetOtherStuff()
{
// also cannot use any non-public members of MyClass
return string.Empty;
}
}
MyClassExtension.GetStuff();
MyClassExtension.GetOtherStuff();
这并不回答这个问题。你建议创建另一个类,而我问如何扩展第一个类而不使用'new MyClass()'符号。为什么我需要以这种方式扩展第一课,这有一个特定的体系结构原因。 – tocqueville
@tocqueville是的。您不能添加静态扩展方法。 .NET不支持它。你可以正常更改'MyClass'并获得你想要的。或者你可以在第二个例子中创建第二个类并调用MyClassExtension.GetOtherStuff()。最后一个选择是使'MyClassExtension:MyClass' ... – Kempeth
不,你不能创建不需要的实例的C#扩展方法类。 (Here's a longer explanation)
选项#1
但是,您可以创建在剃刀意见挂完现有@Html
/HtmlHelper
您的扩展方法。
public static class HtmlHelperExtensions
{
public static string GetOtherStuff(this HtmlHelper helper)
{
return "other stuff";
}
}
选项#2
它也可以创建自己的HtmlHelper
等价,这样你就可以从.cshtml
Razor视图访问它在刚刚同样的方式。
定义一个空类与您的扩展方法扩展:
public class MyCustomHelper
{
// Can just be an empty class.
}
public static class MyCustomHelperExtensions
{
public string GetStuff(this MyCustomHelper helper)
{
return "stuff";
}
}
public static class MyOtherCustomHelperExtensions
{
public string GetOtherStuff(this MyCustomHelper helper)
{
return "other stuff";
}
}
的HtmlHelper
实例从a property on WebViewPage.cs访问。你可以用你自己的类和then configure Razor to use that instead延长WebViewPage
:
public class BaseViewPage<TModel> : WebViewPage<TModel>
{
private MyCustomHelper _foo;
public MyCustomHelper Foo
{
get
{
if (_foo == null)
{
_foo = new MyCustomHelper();
}
return _foo;
}
set
{
_foo = value;
}
}
}
public class BaseViewPage : WebViewPage
{
private MyCustomHelper _foo;
public MyCustomHelper Foo
{
get
{
if (_foo == null)
{
_foo = new MyCustomHelper();
}
return _foo;
}
set
{
_foo = value;
}
}
}
然后从剃刀访问视图这样的:
<div>
@Foo.GetOtherStuff()
</div>
但我不问如何扩展HtmlHelper。如果你阅读我的问题,你会看到我已经做到了。我问如何获得与我自己的自定义c#类相似的结果,以便我可以添加扩展方法而不使用'new MyClass()'表示法。我希望扩展方法像这样可用:'MyClass.MyExtensionMethod()'。 – tocqueville
@tocqueville,我很抱歉,但正如我在答复的第一行中所说的,如果没有类_somewhere_的实例,则无法创建扩展方法。 [这里的答案](http://stackoverflow.com/a/866932/590382)解释了原因。但是,使用我添加的“选项#2”,您可以从Razor视图的视角获得相同的效果。 –
你能不能从BaseClass的继承中每个模块:
public abstract class MyBaseClass
{
public static string SomeProperty { get; set; }
}
//Module 1
public class MyClassOne : MyBaseClass
{
public static string MyFunction()
{
return SomeProperty + "MyClassOne";
}
}
//Module 2
public class MyClassTwo : MyBaseClass
{
public static string MyFunction()
{
return SomeProperty + "MyClassTwo";
}
}
这将允许你这样做:
MyClassOne.MyFunction()
反对的解释会有帮助! – Scrobi
是什么让你觉得'@ Html'不是一个类的实例? –
您能否详细说明一下?我怎样才能达到这个结果,所以我不需要使用符号new MyClass()? – tocqueville
在Razor视图中,@ Html是[此属性](https://msdn.microsoft.com/en-us/library/system.web.mvc.webviewpage.html(v = vs.118).aspx #P:System.Web.Mvc.WebViewPage.Html)的基类。如果您愿意在使用时强制实施基本级别的要求(如Razor),那么您可以实现这一目标。 –