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?

+3


source to share


5 answers


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>

      

0


source


If I understand your question, how about:



public class Foo {
    public static T Bar<T>(this T obj) where T : class {
        return obj;
    }
}

      

0


source


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

      

-1


source


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

      

-1


source


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.

-1


source







All Articles