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();
}
Related
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.
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');
}
}
I have a function in file Code.xaml.cs.
public string send (string url)
{
//some code...
}
I want to call this function from another .cs file.
send("google.com");
But the debugger gives an error! How can I do this?
Whenever calling a dynamic method from a class, you will have to create an instance of that class.
class Test
{
public string send(string url) {}
}
class AnotherClass
{
public AnotherClass()
{
Test t = new Test();
t.send("google.com");
}
}
Otherwise you can simply use the static keyword.
public static string send(..);
If the send method isn't acting as a member function in the class that it's in, you can create a static Helper class.
public static class Helpers
{
public static string send(string url)
{
...
}
}
Then in any other .cs file you can call:
Helpers.send("www.google.com")
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.
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 :)