2017-05-03 7 views
3

Soweit ich weiß, C# lassen Sie uns Erweiterungsmethoden mit einer Instanz einer Klasse nur verwenden:C# -Erweiterungsmethode, die nur mit einer Instanz der Klasse arbeitet. Irgendwie in der Nähe?

public class MyClass 
{ 
    public static string GetStuff() 
    { 
     return string.Empty; 
    } 
} 

public static class MyClassExtension 
{ 
    public static string GetOtherStuff(this MyClass myClass) 
    { 
     return string.Empty; 
    } 
} 

Verbrauch: Jedoch

MyClass.GetStuff(); 
MyClass.GetOtherStuff();  // Cannot resolve symbol 'GetOtherStuff' 
new MyClass().GetOtherStuff(); // This works 

ich, dass der MVC-Framework mir bemerkt erlaubt zu verlängern die HtmlHelpers so, dass ich meine Erweiterungsmethoden verwenden kann, ohne irgendeine Instanz einer Klasse zu erstellen. wenn ich eine Erweiterungsmethode für HtmlHelper wie dies zum Beispiel zu erstellen:

public static string MyHtmlHelper(this HtmlHelper helper) 
{ 
    return string.Empty; 
} 

kann ich es in einem Rasiermesser Ansicht wie folgt verwenden:

@Html.MyHtmlHelper() // no need to instantiate a class 

Ich würde wirklich das gleiche Ergebnis zu erzielen wie mit meinem MyClass, so kann ich tun:

MyClass.GetOtherStuff() 

Wie könnte ich das tun?

+15

Was lässt Sie denken, '@ Html' ist keine Instanz einer Klasse? –

+0

Können Sie bitte ausarbeiten? Wie kann ich dieses Ergebnis erzielen, damit ich nicht die Notation new MyClass() verwenden muss? – tocqueville

+1

In einer Razor-Ansicht ist "@ Html" [diese Eigenschaft] (https://msdn.microsoft.com/en-us/library/system.web.mvc.webviewpage.html (v = vs.118) .aspx) #P: System.Web.Mvc.WebViewPage.Html) der Basisklasse. Wenn Sie bereit sind, eine Basisklasse-Anforderung zum Zeitpunkt der Verwendung aufzuerlegen (wie Razor), können Sie dies erreichen. –

Antwort

-1

können Sie nicht statische Methoden einer Klasse über Erweiterungsmethoden hinzufügen ...

Weil es Sinn machen, nicht. Was Sie vorschlagen, unterscheidet sich nicht von der Erstellung einer zweiten statischen Klasse mit Ihrer neuen Hilfsmethode. Tu das einfach.

Sie wollen, dies zu tun:

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

Die oben nicht möglich ist. Auch wäre es Ihnen keinen Vorteil gegenüber nur tun:

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

Eine letzte Alternative ist, eine Unterklasse erstellen:

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

Dies beantwortet die Frage nicht. Sie schlagen vor, eine andere Klasse zu erstellen, während ich frage, wie ich die erste erweitern kann, ohne die Notation 'new MyClass()' zu verwenden. Es gibt einen bestimmten architektonischen Grund, warum ich die erste Klasse auf diese Weise erweitern muss. – tocqueville

+0

@tocqueville Ja, tut es. Sie können keine statische Erweiterungsmethode hinzufügen. .NET unterstützt es nicht. Sie können entweder 'MyClass' normal ändern und bekommen, was Sie wünschen. Oder Sie können eine zweite Klasse wie in meinem zweiten Beispiel erstellen und 'MyClassExtension.GetOtherStuff()' aufrufen. Eine letzte Alternative ist make 'MyClassExtension: MyClass' ... – Kempeth

0

Nein, man kann nicht eine C# Extension-Methode erstellen, die keine Instanz der benötigt Klasse. (Here's a longer explanation)

Option # 1

aber Sie können erstellen Sie Ihre Erweiterungsmethoden, die die bestehende @Html/HtmlHelper in Razor Ansichten hängen ab.

public static class HtmlHelperExtensions 
{ 
    public static string GetOtherStuff(this HtmlHelper helper) 
    { 
     return "other stuff"; 
    } 
} 

Option # 2

Es ist auch möglich, eigene Äquivalent HtmlHelper, zu erstellen, damit Sie sie dann in genau der gleichen Art und Weise aus einer Ansicht .cshtml Razor zugreifen können.

eine leere Klasse definieren mit Erweiterungsmethoden zu erweitern:

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"; 
    } 
} 

Die HtmlHelper Instanz wird von a property on WebViewPage.cs abgerufen.Sie können WebViewPage mit Ihrem eigenen Klasse erweitern und then configure Razor to use that instead:

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; 
     } 
    } 
} 

und den Zugang dann von einem Rasiermesser wie folgt lesen:

<div> 
    @Foo.GetOtherStuff() 
</div> 
+0

Aber ich frage nicht, wie HtmlHelper zu erweitern. Wenn Sie meine Frage lesen, werden Sie sehen, dass ich das schon getan habe. Ich frage, wie man ein ähnliches Ergebnis mit meiner eigenen benutzerdefinierten C# -Klasse erhält, so dass ich Erweiterungsmethoden hinzufügen kann, ohne die Notation 'new MyClass()' zu verwenden. Ich möchte die Erweiterungsmethoden wie folgt verwenden: 'MyClass.MyExtensionMethod()'. – tocqueville

+0

@tocqueville, tut mir leid, aber wie ich in der ersten Zeile meiner Antwort gesagt habe, können Sie keine Erweiterungsmethode erstellen, ohne eine Instanz einer Klasse _somewhere_ zu haben. [Diese Antwort hier] (http://stackoverflow.com/a/866932/590382) erklärt warum. Sie können jedoch den gleichen Effekt vom Standpunkt Ihrer Razor-Ansichten aus erreichen, indem Sie die "Option # 2" verwenden, die ich hinzugefügt habe. –

-1

Könnten Sie in jedem Ihrer Module aus der Baseclass erben:

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"; 
    } 
} 

Dies würde erlauben Sie zu tun:

MyClassOne.MyFunction() 
+0

Eine Erklärung mit der Down-Abstimmung wäre hilfreich! – Scrobi

-1

Sie können Reflektionen verwenden, um Ihrer Klasse statische Methoden hinzuzufügen. Diese Stackoverflow answer gibt Ihnen möglicherweise eine Idee über die Verwendung von Reflektion zum Hinzufügen von Methoden.

Verwandte Themen