C# Recursion Error - Extension Methods - c#

I get an error here saying that the program could not exit the infinite loop.
public static class Program
{
public static void Main(string[] args)
{
Object obj = new Object();
Console.WriteLine(obj.GetClassName());
}
public static string GetClassName(this object value)
{
return value.GetClassName();
}
}

you need to change your extension method to say:
return obj.GetType().Name;
your extension method is calling itself which is causing the infinite loop/recursion problem.

Related

Get how object is named from the object

Is is posible to get how you named object from the object
For example:
public static void Main(string[] args)
{
Test testVariable = new Test();
}
class Test
{
public Test()
{
Console.WriteLine(GetName());
}
}
would be testVariable
From your code example, it looks like you want the name of the assigned variable. This is not possible without specific requirements on the caller.
There is no real robust solution in C# for this.
The best you can do is using the nameof expression:
public static void Main(string[] args)
{
Test testVariable = new Test(nameof(testVariable));
}
class Test
{
public Test(string variableName)
{
Console.WriteLine(variableName);
}
}
However, this will add little benefit. As you can see, it is a 'static' solution in that it requires to pass in the name of the variable at compile time. Using nameof makes this 'refactor friendly' and gives you basic compile time checking:
public static void Main(string[] args)
{
Test testVariable = new Test(nameof(tstVariable)); // compiler error
}
It opens scenarios like this:
public static void Main(string[] args)
{
Test testVariable1 = new Test(nameof(testVariable1));
Test testVariable2 = new Test(nameof(testVariable2));
}
But as mentioned, this doesn't add very much value, and it's still error prone. For example, nothing stops you from doing something like this:
public static void Main(string[] args)
{
Test testVariable1 = new Test(nameof(testVariable1));
Test testVariable2 = new Test(nameof(testVariable1)); // oops, should be testVariable2
}
Also, as #derpirscher points out, it doesn't stop you from things like this:
Test testVariable1 = new Test(nameof(testVariable1));
Test testVariable2 = testVariable1;
testVariable2.Test(); // still outputs "testVariable1"

Unable to call extension method during runtime for dynamic variable

Below is the sample code and it is throwing error (''string' does not contain a definition for 'ToUpperExtn'') during runtime. How can i handle this.
class Program
{
static void Main(string[] args)
{
dynamic name = "Prasad";
**Console.WriteLine(Convert.ToString(name).ToUpperExtn());** // Error: ''string' does not contain a definition for 'ToUpperExtn''
string name1 = "Prasad";
Console.WriteLine(name1.ToUpperExtn()); // Working fine
}
}
public static class StringExtensions
{
public static string ToUpperExtn(this string value)
{
return value.ToUpper();
}
}

Task.Run Ambiguous Parameter Overloads

I'm using the Task class in C# and want to pass a predefined method that returns a value and not using lambdas to the Task.Run method.
Here is a console app with the code:
static int ThreadMethod()
{
return 42;
}
static void Main(string[] args)
{
Task<int> t = Task.Run(function:ThreadMethod);
WriteLine(t.Result);
}
However, it is returning this error:
The call is ambiguous between the following methods or properties: 'Task.Run<TResult>(Func<TResult>)' and 'Task.Run(Func<Task>)'
I tried doing this to fix it and got my expected result:
Task<int> t = Task.Run((Func<int>)ThreadMethod);
However, I am not sure if I'm doing it right or are there any better solution?
Fix your .Run argument like in this example. Can be copied and pasted into LinqPad to test.
public static void Main(string[] args)
{
Task<int> t = Task.Run(() => ThreadMethod());
WriteLine(t.Result);
}
public static int ThreadMethod()
{
return 42;
}
If you want to see it as a variable to pass check out below:
public static void Main(string[] args)
{
//Func<int> is saying I want a function with no parameters
//but returns an int. '() =>' this represents a function with
//no parameters. It then points to your defined method ThreadMethod
//Which fits the notions of no parameters and returning an int.
Func<int> threadMethod = () => ThreadMethod();
Task<int> t = Task.Run(threadMethod);
Console.WriteLine(t.Result);
}
public static int ThreadMethod()
{
return 42;
}
Here is the Documentation on Func(T), on the left hand menu you can select the different variations of Func() objects.

Can't access the class I just created

I hope this is a simple question. I'm building a simple console application in C#. I have a class:
using System;
using Filter;
public class Params
{
public string key;
public bool distinct;
public List<string> fields;
public string filter;
public int limit;
public int skip;
public bool total;
public List<Tuple<string, GroupType>> group;
public List<Tuple<string, OrderType>> order;
public Params()
{
key = "";
distinct = false;
fields = new List<string>();
filter = "";
group = new List<Tuple<string, GroupType>>();
limit = 0;
order = new List<Tuple<string, OrderType>>();
skip = 0;
total = false;
}
public void AddGroup(string field, GroupType type)
{
group.Add(new Tuple<string, GroupType>(field, type));
}
public void AddOrder(string field, OrderType type)
{
order.Add(new Tuple<string, OrderType>(field, type));
}
}
My program .cs class is:
namespace csharpExample
{
class Program
{
public static void Main(string[] args)
{
Params p = new Params();
Console.WriteLine("Test");
}
}
}
I want to use Params in my program.cs class where Main() is called. I thought I could simply use Params like above. I've also tried to do a using Params; both of these are errors in VS since it can't find the directive. I've also tried adding my own namespace: namespace MyNameSpace; around my Params class. When I do this I still am unable to do a using MyNameSpace; statement as it can't find it.
I just want to extract out a bunch of functions into a class that I can reuse. How do i call this class once it's created?
-Thanks
Thanks for the help.
If you want to access the Params object in the Main function, just add Params p = new Params (); to the Main function at the top.
Most likely your problem is that Main is static, meaning that it can't access other things that aren't static which are outside of it. If you declared Params in the Program class, unless you made it static, it can't be accessed in Main.
Are you talking about calling the constructor or the properties you are setting? You can set the class at the top of your base class and then call the instance of it. But since it is a static class you should probably use a helper method in the main.
namespace Example
{
public class Program
{
Params p = new Params();
string writefromParams() // I exist just to give the string back from params with a nonstatic method
{
return p.key;
}
static void Main(string[] args)
{
Program p2 = new Program(); // set up a new instance of this very class
Console.WriteLine(p2.writefromParams()); // get non static method from class
Console.ReadLine();
}
}
}

How pass delegate to a method, where delegates are non static?

I'm just beginning understanding delegates, I have a class that implemens IDisposable:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
A method (defined in an another class) that is using MyClass:
public class AnotherCLass
{
public static void UseMyClass(MyClass.DoSomething func)
{
using (var mc = new MyClass())
{
// Call the delegate function
mc.func(); // <-------- this is what i should actually call
}
}
}
The actual question: how pass the Zero() function to UseMyClass method? Do I have to create an instance of MyClass (I would like to avoid this...)?
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass(??????????);
}
Is your intent that the instance is provided by the caller of the delegate, and not the creator of the delegate? C# does support such an unbound delegate, it's called an open delegate, and the instance becomes a parameter.
You have to use Delegate.CreateDelegate to create an open delegate, something like this:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
public class AnotherCLass
{
public static void UseMyClass(Converter<MyClass,int> func)
{
using (var mc = new MyClass())
{
// Call the delegate function
func(mc);
}
}
}
AnotherClass.UseMyClass(
(Converter<MyClass, int>)Delegate.CreateDelegate(
typeof(Converter<MyClass, int>),
typeof(MyClass).GetMethod("One")
)
);
Of course, you can do it much more easily with a shim:
AnotherClass.UseMyClass( mc => mc.One() ); // C# 3 or later
AnotherClass.UseMyClass( delegate(MyClass mc) { return mc.One(); } ); // C# 2
Because it's an instance method, if you want to call it, you need an instance. That's simply how the CLR works. However, there are two options you could go with:
Make the member functions static. If they're as simple as returning a static value, there's no reason for them to be instance methods. However, if you do actually require instance data...
Use a singleton instance. This way you don't need to create a new instance every time you want to call your static method.
You can do the latter like this:
public class MyClass
{
private static MyClass singletonInstance;
public static MyClass SingletonInstance
{
get
{
if (singletonInstance == null)
{
singletonInstance = new MyClass();
}
return singletonInstance;
}
}
// the rest of your class implementation
}
Then, you can call your static method like so:
AnotherClass.UseMyClass(MyClass.SingletonInstance.Zero);
Cant be done without instantiation. Heres how you can do it:
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass((new MyClass()).Zero);
}

Categories