2017-05-03 9 views
3

据我所知,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() 

我该怎么做?

+15

是什么让你觉得'@ Html'不是一个类的实例? –

+0

您能否详细说明一下?我怎样才能达到这个结果,所以我不需要使用符号new MyClass()? – tocqueville

+1

在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),那么您可以实现这一目标。 –

回答

-1

您无法通过扩展方法向类添加静态方法...

因为它没有任何意义。你提出的建议与用你的新辅助方法创建第二个静态类没有什么不同。只要做到这一点。

你想这样做:

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(); 
+0

这并不回答这个问题。你建议创建另一个类,而我问如何扩展第一个类而不使用'new MyClass()'符号。为什么我需要以这种方式扩展第一课,这有一个特定的体系结构原因。 – tocqueville

+0

@tocqueville是的。您不能添加静态扩展方法。 .NET不支持它。你可以正常更改'MyClass'并获得你想要的。或者你可以在第二个例子中创建第二个类并调用MyClassExtension.GetOtherStuff()。最后一个选择是使'MyClassExtension:MyClass' ... – Kempeth

0

不,你不能创建不需要的实例的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> 
+0

但我不问如何扩展HtmlHelper。如果你阅读我的问题,你会看到我已经做到了。我问如何获得与我自己的自定义c#类相似的结果,以便我可以添加扩展方法而不使用'new MyClass()'表示法。我希望扩展方法像这样可用:'MyClass.MyExtensionMethod()'。 – tocqueville

+0

@tocqueville,我很抱歉,但正如我在答复的第一行中所说的,如果没有类_somewhere_的实例,则无法创建扩展方法。 [这里的答案](http://stackoverflow.com/a/866932/590382)解释了原因。但是,使用我添加的“选项#2”,您可以从Razor视图的视角获得相同的效果。 –

-1

你能不能从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() 
+0

反对的解释会有帮助! – Scrobi

-1

您可以使用反射将静态方法添加到您的类中。这Stackoverflow answer可能会给你一些关于使用反射来添加方法的想法。

相关问题