The C # extension method only works with an instance of the class. Everything around?
As far as I know, C # only allows extension methods with an instance of a class:
public class MyClass
{
public static string GetStuff()
{
return string.Empty;
}
}
public static class MyClassExtension
{
public static string GetOtherStuff(this MyClass myClass)
{
return string.Empty;
}
}
Using:
MyClass.GetStuff();
MyClass.GetOtherStuff(); // Cannot resolve symbol 'GetOtherStuff'
new MyClass().GetOtherStuff(); // This works
However, I noticed that the MVC framework allows me to extend HtmlHelpers in such a way that I can use my extension methods without instantiating any class instance. For example, if I create an extension method for the HtmlHelper
following:
public static string MyHtmlHelper(this HtmlHelper helper)
{
return string.Empty;
}
I can use it in Razor View like this:
@Html.MyHtmlHelper() // no need to instantiate a class
I would really like to achieve the same result with mine MyClass
, so I can do:
MyClass.GetOtherStuff()
How can i do this?
No, you cannot create a C # extension method that does not require an instance of the class. ( Long explanation here )
Option number 1
However, you can create your own extension methods that depend on existing @Html
/ HtmlHelper
in Razor views.
public static class HtmlHelperExtensions
{
public static string GetOtherStuff(this HtmlHelper helper)
{
return "other stuff";
}
}
Option number 2
You can also create your own equivalent HtmlHelper
so that you can access it exactly as shown in .cshtml
Razor.
Define an empty class for extension using extension methods:
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";
}
}
The instance HtmlHelper
is accessed from a property in WebViewPage.cs . You can extend WebViewPage
with your class and then customize Razor 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;
}
}
}
And then access from the Razor view looks like this:
<div>
@Foo.GetOtherStuff()
</div>
If I understand your question, how about:
public class Foo {
public static T Bar<T>(this T obj) where T : class {
return obj;
}
}
You cannot add static methods to a class using extension methods ...
Because it doesn't make sense. What you suggest is no different than creating a second static class with your new helper method. Just do it.
You want to do this:
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();
The above is not possible . Also, it won't give you any advantage over doing it:
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();
One of the latest alternatives is to create a subclass:
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();
Could you just inherit from BaseClass in each of your modules:
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";
}
}
This will allow you to do:
MyClassOne.MyFunction()
You can use reflection to add static methods to your class. This column answer might give you some insight into using reflection to add methods.