Extension method must be defined in non-generic static class - c#

Error at:
public partial class Form2 : Form
Probable cause:
public static IChromosome To<T>(this string text)
{
return (IChromosome)Convert.ChangeType(text, typeof(T));
}
Attempted (without static keyword):
public IChromosome To<T>(this string text)
{
return (IChromosome)Convert.ChangeType(text, typeof(T));
}

If you remove "this" from your parameters it should work.
public static IChromosome To<T>(this string text)
should be:
public static IChromosome To<T>(string text)

The class containing the extension must be static. Yours are in:
public partial class Form2 : Form
which is not a static class.
You need to create a class like so:
static class ExtensionHelpers
{
public static IChromosome To<T>(this string text)
{
return (IChromosome)Convert.ChangeType(text, typeof(T));
}
}
To contain the extension methods.

My issue was caused because I created a static method inside the partial class:
public partial class MainWindow : Window{
......
public static string TrimStart(this string target, string trimString)
{
string result = target;
while (result.StartsWith(trimString)){
result = result.Substring(trimString.Length);
}
return result;
}
}
When I removed the method, the error went away.

Because your containing class is not static, Extension method should be inside a static class. That class should be non nested as well. Extension Methods (C# Programming Guide)

Related

Define assembly for extension method

I'm trying to use extension method, but the method is defined twice with same name.
Let's say A.Extensions.Ext() and B.Extensions.Ext() I need both references in my class and when trying
using A.Extensions;
using B.Extensions;
class C
{
public void Main()
{
somevalue.Ext();
}
}
I want to somehow define which method to use and I don't know how to do that.
Thanks for help!
There is a way to choose an extension method to be used
Assume you have two classes with extension methods for string
public static class Extension1
{
public static string GetLowerCaseResult(this string str)
{
return str.ToLowerInvariant();
}
}
public static class Extension2
{
public static string GetLowerCaseResult(this string str)
{
return str.ToLowerInvariant();
}
}
to call it in Main method you have to explicitly specify class and method in this way
static void Main(string[] args)
{
var str = "QWERTY";
Extension2.GetLowerCaseResult(str);
Console.Read();
}

How do I use an extension function in another class? C#

I've got a couple of extension functions that I want to transfer between classes.
I have a class called Helpers.cs that I want to have the following:
namespace XYZ
{
public class Helpers
{
public static string Encrypt(this string plainText){
//... do encrypting
}
}
}
In my other class Impliment.cs I want to have the following:
string s = "attack";
s.Encrypt();
How can I implement this?
You're close - extension methods need to be in a static class:
public static class Helpers
{
public static string Encrypt(this string plainText){
//... do encrypting
}
}
If you tried what you posted you'd get a pretty clear compiler error that says basically the same thing:
Extension method must be defined in a non-generic static class
Note that your usage will be slightly different that what you want. You can't do:
string s = "attack";
s.Encrypt();
becasue strings are immutable. Best you can do is overwrite the existing varialbe or store the result in a new one:
string s = "attack";
s = s.Encrypt(); // overwrite
or
string s = "attack";
string s2 = s.Encrypt(); // new variable
You need to make the class, static as well and use a using statement.
Example
FileA.cs:
namespace XYZ {
public static class Helpers {
public static string Encrypt(this string plainText){
//... do encrypting
return plainText;
}
}
}
FileB.cs:
using XYZ;
public class MainClass {
public static void Main() {
string s = "input";
s = s.Encrypt();
Console.WriteLine(s);
}
}
To create an Extension Method, the class must be static, but in general it has to follow these rules:
The class must be public and static
The method must be public and static
The type you want to create the extension method, in C#, must have the first parameter with the this keyword before the parameter
In your case, change the class to be static , for sample:
public static class Helpers
{
public static string Encrypt(this string plainText)
{
//... do encrypting
// return a string;
}
}
I also like to create the classes with name like Type and Extensions sufix, for sample: StringExtensions.cs, DateTimeExtensions.cs, etc.
Obs: Remember it is not a type method, it is just a static method, but you use as a method from a type.

Can I use inheritance with an extension method?

I have the following:
public static class CityStatusExt
{
public static string D2(this CityStatus key)
{
return ((int) key).ToString("D2");
}
public static class CityTypeExt
{
public static string D2(this CityType key)
{
return ((int) key).ToString("D2");
}
Plus other classes with similar extensions that return the key formatted as a "D2"
Is there a way I could inherit from a base class and have the base class provide the functionality so
don't I don't have to repeat the same extension method code?
Update. I am sorry I did not mention this but my classes like CityType are Enums.
You can make the method generic. C# will infer the type:
public static class Extension
{
public static string D2<T> (this T key)
{
return ((int)(object) key).ToString("D2");
}
}
From the comment below, CityType and CityStatus are enums. Therefore you can do this:
public static class Extensions
{
public static string D2(this Enum key)
{
return Convert.ToInt32(key).ToString("D2");
}
}
Original answer:
You can use a generic method and an interface ID2Able:
public static class Extensions
{
public static string D2<T>(this T key) where T : ID2Able
{
return ((int) key).ToString("D2");
}
}
This way the extension method won't show up for absolutely every type; it'll only be available for things you inherit ID2Able from.
Your enums already all inherit from a common base class, namely System.Enum. So you can do this (Enums don't accept "D2" as a format string, but they accept "D", so I added a call to PadLeft):
public static class EnumExtensions
{
public static string D2(this Enum e)
{
return e.ToString("D").PadLeft(2, '0');
}
}

Why is this extension method not working?

public static string ToTrimmedString(this DataRow row, string columnName)
{
return row[columnName].ToString().Trim();
}
Compiles fine but it doesn't show up in intellisense of the DataRow...
My guess is you haven't included the namespace.
Ensure this method is in a static class of its own, separate class from the consuming DataRow.
namespace MyProject.Extensions
{
public static class DataRowExtensions
{
//your extension methods
}
}
In your consumer, ensure you're:
using MyProject.Extensions
I had this same issue. My mistake wasn't that I missed the static class or static method but that the class my extensions were on was not public.
In addition to a missing using, following case with the same symptom may occur:
If you are inside a method of the class itself (or one if its implementors / inheritors), you need to make use of this.
File extension.cs:
namespace a
{
public static void AExt(this A a) {}
}
File user.cs
namespace a
{
class A {}
class B : A
{
this.AExt();
// AExt() will not work without this.
}
}
If you are using different namespaces try this code.
namespace Extensions
{
public static class StringExtensions
{
public static bool IsNumeric(this string inputString)
{
return decimal.TryParse(inputString, out decimal result);
}
}
}
namespace Business
{
// add here other namespaces
using Extensions;
public static class Tools
{
public static bool Check(string inputString)
{
return inputString.IsNumeric();
}
}
}
I had this same issue. My mistake is the argument type is not same: defined one is Session, revokded one is ISession.

How do you write a C# Extension Method for a Generically Typed Class

This should hopefully be a simple one.
I would like to add an extension method to the System.Web.Mvc.ViewPage< T > class.
How should this extension method look?
My first intuitive thought is something like this:
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle(this ViewPage<Type> v)
{
return "";
}
}
}
Solution
The general solution is this answer.
The specific solution to extending the System.Web.Mvc.ViewPage class is my answer below, which started from the general solution.
The difference is in the specific case you need both a generically typed method declaration AND a statement to enforce the generic type as a reference type.
I don't have VS installed on my current machine, but I think the syntax would be:
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
{
return "";
}
}
}
Thanks leddt.
Doing that yielded the error:
The type 'TModel' must be a reference
type in order to use it as parameter
'TModel' in the generic type or method
which pointed me to this page, which yielded this solution:
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
where T : class
{
return "";
}
}
}
It just needs the generic type specifier on the function:
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<Type>(this ViewPage<Type> v)
{
return "";
}
}
}
Edit: Just missed it by seconds!
namespace System.Web.Mvc
{
public static class ViewPageExtensions
{
public static string GetDefaultPageTitle<T>(this ViewPage<T> view)
where T : class
{
return "";
}
}
}
You may also need/wish to add the "new()" qualifier to the generic type (i.e. "where T : class, new()" to enforce that T is both a reference type (class) and has a parameterless constructor.
Glenn Block has a good example of implementing a ForEach extension method to IEnumerable<T>.
From his blog post:
public static class IEnumerableUtils
{
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach(T item in collection)
action(item);
}
}
If you want the extension to only be available for the specified type
you simply just need to specify the actual type you will be handling
something like...
public static string GetDefaultPageTitle(this ViewPage<YourSpecificType> v)
{
...
}
Note intellisense will then only display the extension method when you declare your (in this case) ViewPage with the matching type.
Also, best not to use the System.Web.Mvc namespace, I know its convenient to not have to include your namespace in the usings section, but its far more maintainable if you create your own extensions namespace for your extension functions.
Here's an example for Razor views:
public static class WebViewPageExtensions
{
public static string GetFormActionUrl(this WebViewPage view)
{
return string.Format("/{0}/{1}/{2}", view.GetController(), view.GetAction(), view.GetId());
}
public static string GetController(this WebViewPage view)
{
return Get(view, "controller");
}
public static string GetAction(this WebViewPage view)
{
return Get(view, "action");
}
public static string GetId(this WebViewPage view)
{
return Get(view, "id");
}
private static string Get(WebViewPage view, string key)
{
return view.ViewContext.Controller.ValueProvider.GetValue(key).RawValue.ToString();
}
}
You really don't need to use the Generic version as the generic one extends the non-generic one so just put it in the non-generic base class and you're done :)

Categories

Resources