I am trying to convert Ruby's time to C#, but I am stuck now.
Here's my try:
public static class Extensions
{
public static void Times(this Int32 times, WhatGoesHere?)
{
for (int i = 0; i < times; i++)
???
}
}
I am new to C#, and maybe this one should be easy, and I know I want to use Extensionmethods. But since functions are not 'first class ' in C#, I am stuck for now.
So, what parametertype should I use for of WhatGoesHere?
You can use the Action type:
public static class Extensions
{
public static void Times(this Int32 times, Action<Int32> action)
{
for (int i = 0; i < times; i++)
action(i);
}
}
class Program
{
delegate void Del();
static void Main(string[] args)
{
5.Times(Console.WriteLine);
// or
5.Times(i => Console.WriteLine(i));
}
}
Also have a look here to learn about delegates.
Related
I'm practicing methods, but the problem is I want to separate inputting and sorting, the display method will be the main, I'm having trouble fixing this calling from other class.
This is my script :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CaseProblem
{
class Method
{
static void MethodInput()
{
int[] array = new int[5];
int i;
// loop for accepting values in array
for (i = 0; i < 5; i++)
{
Console.Write("Enter number:\t");
array[i] = int.Parse(Console.ReadLine());
}
}
public static void MethodSort()
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
}
class Program
{
static void Main(int[]array)
{
//sorting array value;
Array.Sort(array); //use array's sort function
Method.MethodSort(array);
Console.ReadLine();
}
}
}
Thank you for your help
First of all Main() ( or "EntryPoint" as we should call it ) cannot have int[] as an input parameter but string[] instead you should learn basics of programming before starting to actually code something.
Second thing :
I want to separate inputting and sorting
You can create an object called Input
public class Input
{
public static void Write(string message)
{
Console.WriteLine(message);
}
public static int? ReadInt(string reason)
{
Write(reason);
string userInput = Console.ReadLine();
int parsed = 0;
if(int.TryParse(userInput, out parsed))
return (int?)parsed;
return null;
}
}
This will be your "InputLogic" which you can use as Input.ReadInt("Please specify your age: ");
Next you can make an Operations object :
public class Operations
{
public void Display(int[] arr)
{
foreach(int i in arr)
{
// and since you have "Input" class that can display things
Input.Write(i.ToString());
}
}
public void Sort(ref int[] arr)
{
Array.Sort(arr);
}
}
Now the last thing is to combine it within your Program
class Program
{
static void Main(string[] args)
{
int[] arr = new int[5];
for(int i = 0; i < arr.Length; i++)
{
int? input = null;
while( !( input = Input.ReadInt("Give me number") ).HasValue ) { }
arr[i] = input.Value;
}
Operations op = new Operations();
op.Display(arr);
op.Sort(ref arr);
op.Display(arr);
}
}
Well, you are missing the parameter for the called function.
public static void MethodSort(int[] array)
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
note: not tested
Okay, you have two errors, both in this method:
public static void MethodSort()
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
as well as how you call it:
Method.MethodSort(array);
The first problem is that the method uses the variable array, which doesn't exist in that method's scope.
The second problem is that you are passing array to the call to Method.MethodSort, but that method isn't configured to take a parameter.
There are two ways to approach solving this: remove array entirely, or change the method to accept it. Now, you obviously cannot remove array, as the whole point is to do stuff with it. Therefore, the logical solution is to add array as a parameter to your method:
public static void MethodSort(int[] array)
{
foreach (int i in array)
{
Console.Write(" {0}", i);
}
}
Code:
using System.IO;
using System;
using System.Reflection;
using System.Collections.Generic;
class AnyClass
{
delegate void Del(string str);
static void Main()
{
List<Del> listDel = new List<Del>();
listDel.Add(delegate(string str) { });
Console.WriteLine( listDel[0].Method.ToString() );
listDel.Add(delegate(string str) { });
Console.WriteLine( listDel[1].Method.ToString() );
for (int i = 0; i < 2; i++)
{
listDel.Add(delegate(string str) { });
}
Console.WriteLine( listDel[2].Method.ToString() );
Console.WriteLine( listDel[3].Method.ToString() );
}
}
Output:
Void m__0(System.String)
Void m__1(System.String)
Void m__2(System.String)
Void m__2(System.String)
Why do the delegates instantiated in the loop "point" to the same method (m__2) whereas the ones instantiated outside the loop point to two different methods (m__0 and m__1)?
Is there any way how to instantiate delegates that point to different/unique methods inside a loop?
Example of usage: I need to have delegates as keys in a dictionary, so they need to be unique. Instantiation inside a loop is necessary to provide enough of flexibility.
Why do the delegates instantiated in the loop "point" to the same
method (m__2) whereas the ones instantiated outside the loop point to
two different methods (m__0 and m__1)?
Because behind the scenes the compiler is caching the delegate creation. When you create the first two delegates, the compiler doesn't have knowledge that they are the same, so he creates two different cached delegates and two named methods. Inside your for loop, the compiler is optimizing by only instantiating the delegate once. He can be certain that it's the same delegate each time, instantiate it once, then cache it.
When you de-compile your code, it actually looks like this:
private delegate void Del(string str);
[CompilerGenerated]
private static Launcher.Del CS$<>9__CachedAnonymousMethodDelegate3;
[CompilerGenerated]
private static Launcher.Del CS$<>9__CachedAnonymousMethodDelegate4;
[CompilerGenerated]
private static Launcher.Del CS$<>9__CachedAnonymousMethodDelegate5;
private static void Main()
{
List<Launcher.Del> listDel = new List<Launcher.Del>();
List<Launcher.Del> arg_24_0 = listDel;
if (Launcher.CS$<>9__CachedAnonymousMethodDelegate3 == null)
{
Launcher.CS$<>9__CachedAnonymousMethodDelegate3 =
new Launcher.Del(Launcher.<Main>b__0);
}
arg_24_0.Add(Launcher.CS$<>9__CachedAnonymousMethodDelegate3);
Console.WriteLine(listDel[0].Method.ToString());
List<Launcher.Del> arg_5D_0 = listDel;
if (Launcher.CS$<>9__CachedAnonymousMethodDelegate4 == null)
{
Launcher.CS$<>9__CachedAnonymousMethodDelegate4 =
new Launcher.Del(Launcher.<Main>b__1);
}
arg_5D_0.Add(Launcher.CS$<>9__CachedAnonymousMethodDelegate4);
Console.WriteLine(listDel[1].Method.ToString());
for (int i = 0; i < 2; i++)
{
List<Launcher.Del> arg_9A_0 = listDel;
if (Launcher.CS$<>9__CachedAnonymousMethodDelegate5 == null)
{
Launcher.CS$<>9__CachedAnonymousMethodDelegate5 =
new Launcher.Del(Launcher.<Main>b__2);
}
arg_9A_0.Add(Launcher.CS$<>9__CachedAnonymousMethodDelegate5);
Console.WriteLine(listDel[2 + i].Method.ToString());
}
}
[CompilerGenerated]
private static void <Main>b__0(string str)
{
}
[CompilerGenerated]
private static void <Main>b__1(string str)
{
}
[CompilerGenerated]
private static void <Main>b__2(string str)
{
}
I would definitely not rely on a delegate being a proper key for a Dictionary.
Is there any way how to instantiate delegates that point to
different/unique methods inside a loop?
You can force the delegate to be a "fresh instance" only by explicitly creating a new Del instance yourself and passing a new named method each time. There are other more "fishy" ways of doing so, but I wouldn't recommend taking those paths just to get a new delegate.
Is there any way how to instantiate delegates that point to different/unique methods inside a loop?
You can't make each loop iteration create a different method because methods are hard-coded into the assembly. Their number is fixed while the loop could be unbounded.
You can make each syntactic appearance of a lambda have a different method by using some kind of hack:
Action<int> x = i => {
if (Environment.CurrentManagedThreadId < 0 /*always false*/)
Console.WriteLine(i + uniqueIntegerHere);
};
This forces each method body to be unique and the compiler cannot ever optimize this away. You can of course pull the body into a helper method.
If you want unique delegates per loop iteration you either need to create methods at runtime or keep a set of statically compiled methods:
void F1() { }
void F2() { }
void F3() { }
...
T4 templates come to mind.
Yet another way similar to the one proposed by #usr. You can force compiler to create a new instance of delegate object using reflection method Delegate.CreateDelegate(type, this, methodInfo). The trick goes at the point where this parameter is always a new object thus forcing myMethod being called on it and thus each delegate actually represents a different context for compiler.
This requires the method for delegation to be inside a separate class, which you can instantiate. I am not sure this requirement fits you actual task. Perhaps you will be inspired for another solution based on this one...
using System.IO;
using System;
using System.Reflection;
using System.Collections.Generic;
class AnyClass
{
delegate void Del(string str);
private static Dictionary<Del, string> dict = new Dictionary<Del, string>();
static void Main()
{
List<Del> listDel = new List<Del>();
int count = 10;
for (int i = 0; i < count; i++)
{
listDel.Add(factory());
dict.Add(listDel[i ], "Delegate " + (i));
}
for (int i = 0; i < count; i++)
{
Console.WriteLine(listDel[i].Method.ToString());
listDel[i].Invoke((i).ToString());
}
Console.ReadLine();
}
public class DelegateEncapsulator
{
private int _number;
public DelegateEncapsulator(int number)
{
_number = number;
}
public void myMethod(string str) {
Console.WriteLine("Delegate " + _number + " " + str);
}
}
private static int delegateCounter = 100;
private static Del factory()
{
var obj = new DelegateEncapsulator(delegateCounter++);
var ret = (Del)Delegate.CreateDelegate(typeof(Del), obj,
typeof(DelegateEncapsulator).GetMethod("myMethod"));
return ret;
}
}
This code adds all delegates into a dictionary. You can play with number elements to be added.
Hope this helps
This code has been taken from another website :
using System;
using System.Threading.Tasks;
public class Program {
private static Int32 Sum(Int32 n)
{
Int32 sum = 0;
for (; n > 0; n--)
checked { sum += n; }
return sum;
}
public static void Main() {
Task<int32> t = new Task<int32>(n => Sum((Int32)n), 1000);
t.Start();
t.Wait();
// Get the result (the Result property internally calls Wait)
Console.WriteLine("The sum is: " + t.Result); // An Int32 value
}
}
I don't understand the purpose of using the private static method and not any other normal public method.
Thanks
The method is static because it's used from a static context, so it can't be non-static.
The method is probably private because there's no reason to make it public.
This is because you have Main method is static and you can not call non-static method from static method without make object of that class as non-static methods are called with object.
If make the Sum method non-static you will have to call it on object of Program class
private Int32 Sum(Int32 n)
{
//your code
}
Calling will be changed as
Task<Int32> t = new Task<Int32>(n => new Program().Sum((Int32)n), 1000);
I am new to threading, so please forgive me if my question is at an amateur level.The example below is a simplified version of what I am trying to do. This works if method go is static, I want it to work when Go is not static. How do I make it work.
using System;
using System.Threading;
using System.Diagnostics;
public class ThreadPoolExample
{
static void Main()
{
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(Go, i);
}
Console.ReadLine();
}
void Go(object data)
{
Console.WriteLine(data);
}
}
If someone can make this work and add a notification that all threads have completed execution, that would be awesome.
I suspect there it has nothing to do with Go being static or not, but rather the fact that you can't call/use instance method "Go" from static "Main". Either both need to be static or you need to call/use Go on an instance of your class like:
ThreadPool.QueueUserWorkItem(value => new ThreadPoolExample().Go(value), i);
Do it in this way
class ThreadPoolExample
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
ThreadPoolExample t = new ThreadPoolExample();
ThreadPool.QueueUserWorkItem(t.Go, i);
}
Console.ReadLine();
}
void Go(object data)
{
Console.WriteLine(data);
}
}
Every time I need to do something N times inside an algorithm using C# I write this code
for (int i = 0; i < N; i++)
{
...
}
Studying Ruby I have learned about method times() which can be used with the same semantics like this
N.times do
...
end
Code fragment in C# looks more complex and we should declare useless variable i.
I tried to write extension method which returns IEnumerable, but I am not satisfied with the result because again I have to declare a cycle variable i.
public static class IntExtender
{
public static IEnumerable Times(this int times)
{
for (int i = 0; i < times; i++)
yield return true;
}
}
...
foreach (var i in 5.Times())
{
...
}
Is it possible using some new C# 3.0 language features to make N times cycle more elegant?
A slightly briefer version of cvk's answer:
public static class Extensions
{
public static void Times(this int count, Action action)
{
for (int i=0; i < count; i++)
{
action();
}
}
public static void Times(this int count, Action<int> action)
{
for (int i=0; i < count; i++)
{
action(i);
}
}
}
Use:
5.Times(() => Console.WriteLine("Hi"));
5.Times(i => Console.WriteLine("Index: {0}", i));
It is indeed possible with C# 3.0:
public interface ILoopIterator
{
void Do(Action action);
void Do(Action<int> action);
}
private class LoopIterator : ILoopIterator
{
private readonly int _start, _end;
public LoopIterator(int count)
{
_start = 0;
_end = count - 1;
}
public LoopIterator(int start, int end)
{
_start = start;
_end = end;
}
public void Do(Action action)
{
for (int i = _start; i <= _end; i++)
{
action();
}
}
public void Do(Action<int> action)
{
for (int i = _start; i <= _end; i++)
{
action(i);
}
}
}
public static ILoopIterator Times(this int count)
{
return new LoopIterator(count);
}
Usage:
int sum = 0;
5.Times().Do( i =>
sum += i
);
Shamelessly stolen from http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html
If you are using .NET 3.5 then you can use the extension method Each proposed in this article, and use it to avoid classic loop.
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach(T item in source)
{
action(item);
}
}
}
This particular extension method spot
welds an Each method on anything that
implements IEnumerable. You know
this because the first parameter to
this method defines what this will be
inside the method body. Action is a
pre-defined class that basically
stands in for a function (delegate)
returning no value. Inside the method,
is where the elements are extracted
from the list. What this method
enables is for me to cleanly apply a
function in one line of code.
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
Hope this helps.
I wrote my own extension that add Times to Integer (plus some other stuff). You can get the code here : https://github.com/Razorclaw/Ext.NET
The code is very similar to Jon Skeet answer:
public static class IntegerExtension
{
public static void Times(this int n, Action<int> action)
{
if (action == null) throw new ArgumentNullException("action");
for (int i = 0; i < n; ++i)
{
action(i);
}
}
}