does ToInt32() is extension method in C#? specially Convert.ToInt32()
No. An extension method's raison d'être is to allow the instance method invocation syntax to be used for methods declared outside the type. You'll find that you cannot do that with any of the Convert.ToInt32 methods.
For example, the type String does not have a ToInt32(String) member method. If you wanted to convert a String to an Int32, you could write a static method like this:
public static class StringConverters
{
public static Int32 ToInt32(String number)
{
return Int32.Parse(
number,
NumberStyles.Integer,
CultureInfo.CurrentCulture.NumberFormat);
}
}
And call it like this:
var n = StringConverters.ToInt32("12345");
or, (in some cases this would be acceptable)
using static StringConverters;
…
var n = ToInt32("12345");
But, if you want to call with the instance method invocation syntax, you would create an extension method as static method with first parameter this in a non-generic, non-nested, static class:
public static class StringConverters
{
public static Int32 ToInt32(this String number)
{
return Int32.Parse(
number,
NumberStyles.Integer,
CultureInfo.CurrentCulture.NumberFormat);
}
}
And call it like this:
var n = "12345".ToInt32();
The String type still does does not have a ToInt32(String) member. It just appears that the ToInt32 declaration has extended that type. That's why it is called an extension method.
Convert.ToInt32() is not an extension method, it is a static method inside the static class Convert.
However, you can create an extension method to do that like this:
public static class MyExtensions
{
public static Int32 ToInt32(this object obj)
{
return Convert.ToInt32(obj);
}
}
Usage:
object obj = 5;
int five = obj.ToInt32();
You can press F12 on ToInt32() and you can see
namespace System
{
public static class Convert
{
public static int ToInt32(object value);
}
}
So not a extension but static
The extension in C# in something like below
public static int MethodName(this String str)
{
...
}
Related
As you know, we can convert to string using Convert.ToString or ToString. I want to make the same thing for integer, byte etc. Furthermore, I want to see this method for every object when I put dot.
How should I write the method?
You are looking for a extension method. just create a static class and a static method inside it like:
public static class Exts
{
public static int ToInt32(this string x)
{
int result = 0;
int.TryParse(x, out result);
return result;
}
}
of course my method is a sample and it just returns 0 for any string value that is not castable to int, however you may write any code, accept default value as argument, throw exception,...
Then you can use it like:
string a = "123";
int b = a.ToInt32();
int c = "321".ToInt32();
Write a generic extension that converts any type to Int32:
public static class ObjectExt {
public static int ToInt<T>(this T obj) => Convert.ToInt32(obj);
}
I have about 1000 classes in which i need to count the number of properties of. I have the following code:
public static int NumberOfProperties()
{
Type type = typeof(C507);
return type.GetProperties().Count();
}
I could copy and paste this in to each class changing the typeof parameter but this seems a bit tedious.
Is there anyway to make an extensions method to do this by just doing var nop = C507.NumberOfProperties();?
Just to add to the answers suggesting an extension for object for completeness: you can also consider implementing an extension only for Type:
public static int GetPropertyCount(this Type t)
{
return t.GetProperties().Length;
}
and use it like this:
typeof(C507).GetPropertyCount();
The advantage is that you can get the number of properties directly from the type and do not have to create an instance first.
So you can write an extension method that uses object or one that uses type.
public static class ObjectExtensions
{
public static int GetNumberOfProperties(this object value)
{
return value.GetType().GetProperties().Count();
}
public static int GetNumberOfProperties(this Type value)
{
return value.GetProperties().Count();
}
}
Usage:
new C507().GetNumberOfProperties();
typeof(C507).GetNumberOfProperties();
However, you explicitly state two things:
I could copy and paste this in to each class changing the typeof
I have about 1000 classes
You'll likely not want to instantiate a 1000 classes or copy and paste typeof() 1000 times
In this case, you will want to read them all from the Assembly.
So something like:
typeof(SomeClass).Assembly.GetTypes().Select(x => new
{
x.Name,
PropertyCount = x.GetType().GetProperties().Count()
});
Where SomeClass is a class (doesn't matter which) where all the classes reside.
I just simply select them out into an anonymous object which contains the Types name and property count.
This:
typeof(SomeClass).Assembly
Is just a convience way to get the assembly. There are other ways.
Assembly.GetAssembly(typeof(Program)).GetTypes()
Assembly.GetCallingAssembly().GetTypes()
Assembly.Load("Some Assemble Ref").GetTypes()
You can do allsorts with the types that you find. If you select out the Type itself, you can instantiate it later using Activator.CreateInstance (if it has parameterless constuctor). You can also auto fill the properties with reflection as well.
It is impossible to have a static extension method as you imagine it. That being said, it would be possible to create a generic method in a helper class as follows.
public static int NumberOfProperties<T>()
{
Type type = typeof(T);
return type.GetProperties().Count();
}
Given a type SomeType it could be called as int n = NumberOfProperties<SomeType>().
You could make an extension method on object like this:
public static int PropertyCount(this object thing)
{
return thing.GetType().GetProperties().Count();
}
And use it on any object you like:
var x = "some string";
var numProps = x.PropertyCount();
If you want to have an extension method on object:
public static ObjectExtensions
{
public static int NumberOfProperties(this object value)
{
if (null == value)
throw new ArgumentNullException("value"); // or return 0
// Length: no need in Linq here
return value.GetType().GetProperties().Length;
}
}
...
C507 myObj = new C507();
// How many properties does myObj instance have?
int propCount = myObj.NumberOfProperties();
If you want to have an extesnion method on Type:
public static TypeExtensions
{
public static int NumberOfProperties(this Type value)
{
if (null == value)
throw new ArgumentNullException("value"); // or return 0
// Length: no need in Linq here
return value.GetProperties().Length;
}
}
...
// How many properties does C507 type have?
int propCount = typeof(C507).NumberOfProperties();
There are a couple of ways to do this that are variations of the same thing.
You can pass the Type as an argument to a method:
public static class Helper {
public static int NumberOfProperties(Type type)
{
return type.GetProperties().Count();
}
}
Which you would call like this:
// Imagine you have a class called MyClass
var result = Helper.NumberOfProperties(typeof(MyClass));
You use use the generic system in C# to make the syntax a little cleaner. That would look like this:
public static class Helper {
// Notice the argument was removed and
// the use of the "generic" syntax <T>
public static int NumberOfProperties<T>()
{
var type = typeof(T);
return type.GetProperties().Count();
}
}
And you would call it like this:
var result = Helper.NumberOfProperties<MyClass>();
You could also use "Extensions" which allow you to call it as if it was a method that belonged to your classes.
public static class Helper {
// notice the `this` keyword before the parameter
// this is what tells C# that this is an extension method
public static int NumberOfProperties<T>(this T #this)
{
var type = typeof(T);
return type.GetProperties().Count();
}
}
This will allow you to call the method like this:
var instance = new MyClass();
var result = instance.NumberOfProperties();
In this example I used the generic syntax so that it applies to any type of object. If you wanted to limit it to only objects that inherit from a specific interface or base class you would just change it from using the generic syntax to using the base class/interface. Like this:
public static class Helper {
// notice the type got changed from a generic <T>
// to specifying the exact class you want to "extend"
public static int NumberOfProperties(this MyBaseClass #this)
{
var type = typeof(T);
return type.GetProperties().Count();
}
}
As #rené-vogt mentioned you can also create the extension method so that it extends the type Type instead. See his answer in this thread: https://stackoverflow.com/a/38455233/984780
You can make a generic extension method which can apply to all types:
public static int PropertyCount<T>(this T obj)
{
return typeof(T).GetProperties().Length;
}
This will apply to all types including value types (I.E. structs) which applying to object will not. Thanks to piedar for pointing out my mistake here, applying to object does still add this extension method to value types.
If your classed can implement an interface, then you can extend that interface.
public interface IExtensible {
}
class C507 : IExtensible {
}
public static int NumberOfProperties(this IExtensible extensible)
{
Type type = extensible.GetType();
return type.GetProperties().Count();
}
That being said, having hundreds of (generated?) classes looks like a bad solution to begin with.
Regarding anonymous methods, and given a method "WriteConditional" that has the first parameter as a Func, is there a way to even eliminate the extra "() => " syntax?
It seems like you should be able to, since its unambiguous as long as there's no additional overload that would accept string, right?
void Program()
{
IDictionary<string,string> strings = new Dictionary<string,string>() { {"test","1"},{"test2","2"}};
//seems like this 'should' work, because WriteConditional has no other overload
//that could potentially make this ambiguous
WriteConditional(strings["test"],"<h3>{0}</h3>");
//since WriteConditional_2 has two overloads, one that has Func<string> and another with string,
//the call could be ambiguous, so IMO you'd definitely have to "declare anonymous" here:
WriteConditional_2(()=>strings["test"],"<h3>{0}</h3>");
}
void WriteConditional(Func<string> retriever, string format)
{
string value = retriever.Invoke();
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
void WriteConditional_2(Func<string> retriever, string format)
{
string value = retriever.Invoke();
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
void WriteConditional_2(string value, string format)
{
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
No, there is no such way. You could however, cheat and provide your own overload:
void WriteConditional(Func<string> retriever, string format)
{
var value = retriever();
if(string.IsNullOrEmpty(value)==false)
Console.WriteLine(string.Format(format,value));
}
void WriteConditional(string value, string format)
{
WriteConditional(() => value, format);
}
is there a way to even eliminate the extra "() => " syntax?
I also think the answer is no but you can do something if your func returns a custom class by using operator overloading.
This could be possible for other types if you could use operation overloading with extention methods
using System;
public class MyClass
{
public static implicit operator Func<MyClass>(MyClass obj)
{
return () => { Console.WriteLine("this is another cheat"); return new MyClass(); };
}
}
public class Program
{
static void Main(string[] args)
{
MyClass x = new MyClass();
WriteConditional(x);
Console.ReadLine();
}
static void WriteConditional(Func<MyClass> retriever) { }
}
I'm trying to create a class that at runtime can be pointed to various data inputs. To do this I am trying to use delegates. I have a worker method that returns a string (in the actual implementation, there would be others to choose from). The return value of the delegate is then returned from a method exposed to the rest of the code.
private delegate string delMethod();
private static delMethod pntr_Method = new delMethod(OneDelegateMethod);
public static string ExposedMethod()
{
return pntr_Method;
}
public static string OneDelegateMethod()
{
return "This is a string";
}
I'm getting this error
Cannot implicitly convert type 'OB.DataBase.delMethod' to 'string'
I'm puzzled why I get this, when this method has worked for bools and IDataReaders.
If you want to call the delegate and return the value, you have to use "()":
public static string ExposedMethod()
{
return pntr_Method();
}
You need to call the delegate in order for it to return a string value. Delegates are really just pointers to methods, and need to be called using parenthesis in order to execute the method they point to.
Here is a fixed version of your code:
private delegate string delMethod();
private static delMethod pntr_Method = new delMethod(OneDelegateMethod);
public static string ExposedMethod()
{
return pntr_Method();
}
public static string OneDelegateMethod()
{
return "This is a string";
}
You have to invoke the target method:
public static string ExposedMethod()
{
return pntr_Method();
}
I want to write an extension method for nullable int so that I could write the code int?.TryParse(“32”) in a similar manner to writing int.TryParse(“32”). The following method signature is not valid:
public static int? TryParse(this Type(int?), string input)
{
...
}
Is there any solution?
public static int? TryParse(this string input) {
int i;
return int.TryParse(input, out i) ? i : (int?)null;
}
Usage:
var i = yourString.TryParse();
I think you may want to define a generic method like this:
public static T? TryParse<T>(this string input) where T : struct {
T i = default(T);
object[] args = new object[] { input, i };
var tryParse = typeof(T).GetMethod("TryParse",
new[] { typeof(string), typeof(T).MakeByRefType() });
if(tryParse != null){
var r = (bool) tryParse.Invoke(null, args);
return r ? (T) args[1] : (T?)null;
}
return (T?)null;
}
//Usage
double? d = yourString.TryParse<double>();
int? i = yourString.TryParse<int>();
Using the generic method above is very convenient but the performance may be reduced a little due to using reflection. If you just want some TryParse methods for some types int, double, ... You should define particular method for each one, named them differently like TryParseInt, TryParseDouble, TryParseDecimal, ... and apply the similar code to the first code snippet I posted above.
Extension methods look like instance methods, but are in fact static methods. When you define an extension method, you can extend instances of a class with a new method, but you cannot extend the class itself with a new static method.