Unable to Access Extension Method in Main Method - c#

I am using extension method to convert string to integer. But i am not able to access extension method in main method. What was i did wrong. My Code is below
public static class ConvertIntExtensionMethod
{
public static int ConvertToInt(this int str) {
int value;
value = Convert.ToInt32(str);
return value;
}
}
static void Main(string[] args)
{
string str = "100";
//int i = 10;
//bool result = i.IsGreaterThan(100);
int result = str.ConvertIntExtensionMethod(); //Here is the problem
Console.WriteLine(result);
Console.ReadLine();
}
please try to help me thank you...

Extension methods must be defined in a top level static class, it seems that your ConvertIntExtensionMethod class is a nested class
If you want to add this method to string, the type of the param must be this string
Call str.ConvertToInt() instead of str.ConvertIntExtensionMethod()

str does not contain any member known as ConvertIntExtensionMethod(). You need to do this:
public static class ConvertIntExtensionMethod
{
public static int ConvertToInt(this string str)
{
int value;
value = Convert.ToInt32(str);
return value;
}
}
class Program
{
static void Main(string[] args)
{
string str = "5";
//int i = 10;
//bool result = i.IsGreaterThan(100);
int result = ConvertIntExtensionMethod.ConvertToInt(str); //Here is the problem
Console.WriteLine(result);
Console.ReadLine();
}
}
It will convert an integer as a string to an int.

I am give the wrong parameter type in the extension method. Main method passing string value but extension method parameter is integer. This is the problem what i found.
Updated code in Extension method is given below
public static int ConvertToInt(this string str)
{
int value;
value = Convert.ToInt32(str);
return value;
}

Related

C# constructors sharing code and then referencing properties already set [duplicate]

I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.

Create definition to integer

I receive this kind of error:
int does not contain a definition for 'childConvert' and no accessible extension method 'childconver' accepting a first argument of type'int' could be found (are you missing assembly reference)
In Main Method:
int n = 10;
string Name = n.ChildConver();
In Child Method:
public static string ChildConver(this int Name)
{
string Namecovert = Convert.ToString(Name) + "Convertion";
return Namecovert;
}
Try to put it in a static class.
public static class Common
{
public static string ChildConver(this int name)
{
return name + "Convertion";
}
}
Extension methods must be defined in a non-generic static class.
Ref: MSDN
Define extension method in separate class.
public static class IntHelper
{
public static string ChildConver(this int Name)
{
string Namecovert = Convert.ToString(Name) + "Convertion";
return Namecovert;
}
}
public static string ChildConver(this int Name)
{
retunt Name + "Convertion";
}
Try ToString()
public class Program
{
public static void Main()
{
int n = 10;
string Name = n.ChildConver();
System.Console.WriteLine(Name);
}
}
public static class Ext
{
public static string ChildConver(this int Name)
{
string Namecovert = Name.ToString() + " Convertion";
return Namecovert;
}
}

Iteration through properties with custom attributes in a class

I've got a class like this with some custom attributes. I'm not sure whether i actually have to implement these.
[AttributeUsage(AttributeTargets.Field)]
private class IsValue : Attribute { }
[AttributeUsage(AttributeTargets.Field)]
private class IsRep : Attribute { }
[AttributeUsage(AttributeTargets.Class)]
private class IsConstant : Attribute { }
public static class Constants
{
[IsConstant]
public static class EulerGamma
{
[IsValue]
public const double Value = 0.5772156649015;
[IsRep]
public const string Str = "γ";
}
[IsConstant]
public static class EulerNumber
{
[IsValue]
public const double Value = 2.718281828459;
[IsRep]
public const string Str = "e";
}
[IsConstant]
public static class Pi
{
[IsValue]
public const double Value = 3.1415926535898;
[IsRep]
public const string Str = "π";
}
[IsConstant]
public static class GoldenRatio
{
[IsValue]
public const double Value = 1.6180339887499;
[IsRep]
public const string Str = "φ";
}
}
Let's say this is in some class "MyMathClass", where I'd like to implement a method like this:
string ValueOrString(double x)
This method would return string representation of the constant if the number passed is equal to the constant, else it would return the original number.
So, if i passed exactly 3.1415926535898 this method would give me the string "π".
If is passed for example 2.5315621321 this would return me "2.5315621321" (string).
Would you please help me out?
I would create a class that uses a dictionary:
public static class Constants
{
static Dictionary<double, string> constantNames;
static Constants()
{
Constants.constantNames = new Dictionary<double, string>();
Constants.constantNames.Add(3.1415926535898, "π");
Constants.constantNames.Add(2.718281828459, "e");
}
public static string ValueOrString(double value)
{
if (constantNames.ContainsKey(value))
{
return constantNames[value];
}
else
{
return value.ToString();
}
}
}
When the function string ValueOrString(double value) is called, you can check if the provided value exists in the dictionary. If it exists, you retrieve the name of the constant from it. Otherwise, you return the value as a string.

Passing variable from another class as input but not getting value back

I have a class where I hold some variables :
public class PreviousCalls
{
private static int bot1Call;
public static int previousBot1Call
{
get { return bot1Call; }
set { bot1Call = value; }
}
private static int bot2Call;
public static int previousBot2Call
{
get { return bot2Call; }
set { bot2Call = value; }
}
private static int bot3Call;
public static int previousBot3Call
{
get { return bot3Call; }
set { bot3Call = value; }
}
private static int bot4Call;
public static int previousBot4Call
{
get { return bot4Call; }
set { bot4Call = value; }
}
private static int bot5Call;
public static int previousBot5Call
{
get { return bot5Call; }
set { bot5Call = value; }
}
}
I need to pass those variables as parameters to a lot of methods in my other class here's how I do it :
void AI(... , int previous)
AI(... , PreviousCalls.previousBot1Call);
So the parameter previous is changing the way it should but the variables from class PreviousCalls are not changing at all, why is that ?
int is value type, so there is a copy of 'previous value' passed to method body. So changing a variable inside method doesn't cause the original value change:
public void Test(int a)
{
a = 10;
}
int t = 11;
Test(t);
//t is still 11, because Test method operates on copy of t
To change original value you must use ref or out:
void AI(..., ref int previous) { ... }
int param;
AI(..., ref param); //when ref is used, original variable wil be changed.
PreviousCalls.previousBot1Call = param;
Unfortunately, you cannot use it like this:
AI(... , ref PreviousCalls.previousBot1Call); // compile-time error
// member-access is forbidden wtih out/ref
AI(,.., ref 10); // compile-time error
Another attempt:
interface IAIParam
{
int Previous { get; set; }
// other params
}
void AI(IAIParam p)
{
p.Previous += 1;
//....
}
And then implementaiton:
internal class MyBotProxy : IAIParam
{
public int Previous
{
get { return PreviousCalls.previousBot1Call; }
set { PreviousCalls.previousBot1Call = value; }
}
}
usage:
var myProxy = new MyBotProxy();
AI(myProxy);
Most commonly methods do not change any values outside of their method scope, instead they return a new value. Only methods that accept the parameter by reference instead of value can change the value of the parameter in the calling context.
This article on MSDN is a great starting point for understanding how to pass parameters by reference instead of value.
Please note that you will not be able to pass a class member as a ref or out parameter. If you wish to update part of a class via reference, you will need to pass the entire class object as the reference.

How to pass in the "modifier" string returned by the function?

class test
{
public String get() {return s;}
private String s="World";
}
class modifier
{
public static void modify(ref String v)
{
v+="_test";
}
}
String s1="Earth";
modifier.modify(ref s1); <-------- OK
test c=new test();
modifier.modify(ref c.get()); <------- Error
How to pass in the "modifier" string returned by the function?
Assignment through another String object is unacceptable. So how will the copy is created.
You're trying to write C++ code in C#. You'll need to approach this the C# way.
Add a property for test.s, instead of a method called "get()".
We'll call this new property "MyString" in the code below:
class test
{
public String MyString
{
get
{
return s;
}
set
{
s = value;
}
}
private String s = "World";
}
class modifier
{
public static string modify(String v)
{
return v + "_test";
}
}
test c = new test();
c.MyString = modifier.modify(c.MyString);
If you dont like Matthew Watson's answer and you want to stay to your approach, the way to go is by using StringBuilder.That is a String that can change its value without creating a new one!
What i mean:
Normal String's value cant be changed, what is happening is that a new String is being created....and the pointer(that points to the String you want to change its value) points from now on to this new String. All other pointers....that "were pointing" to the old String .....are still pointing...to the old String!(the String's value didnt change!)
I am not sure if thats clear enough but you have to understand this if you want to play with Strings.This is exactly why s1 cant change its value.
The workaround is with StringBuilder:
class test
{
public StringBuilder get() { return s; }
private StringBuilder s = new StringBuilder("World");
}
class modifier
{
public static void modify(StringBuilder v)
{
v.Append("_test");
}
}
And some test code : (of course all this comes with processing cost...but i dont think that will be an issue for now)
StringBuilder s1 = new StringBuilder("Earth");
System.Diagnostics.Debug.WriteLine("earth is {0}", s1);
modifier.modify(s1); //<-------- OK
System.Diagnostics.Debug.WriteLine("earth is {0}",s1);
test c=new test();
StringBuilder aa=c.get();
System.Diagnostics.Debug.WriteLine("earth is {0}", aa);
modifier.modify(aa); //<------- Error(not anymore)
System.Diagnostics.Debug.WriteLine("earth is {0}", c.get());
Before you use the code try to understand how String and StringBuilder works
You have to create a temporary variable:
string tmp = c.get();
modifier.modify(ref tmp);
Because you are passing your parameter by reference.
The class test is designed such that its field s can't be reassigned (changed to point to a new object) from outside the class. That's because s is private, and the get() method only returns s, hence can't reassign it.
Either change the class test to allow the outside world to reassign s somehow, or use reflection to access a private field from the outside.
You can use a property with a get/set-eccessor and then pass to the modify() a test object:
class test
{
public String myString
{
get { return s; }
set { s = value; }
}
private String s="World";
}
class modifier
{
public static void modify(test myTest)
{
myTest.myString += "_test";
}
}
test c = new test();
modifier.modify(c);
Console.WriteLine(c.myString); //World_test

Categories