I was wondering if someone could explain what Func<int, string> is and how it is used with some clear examples.
Are you familiar with delegates in general? I have a page about delegates and events which may help if not, although it's more geared towards explaining the differences between the two.
Func<T, TResult> is just a generic delegate - work out what it means in any particular situation by replacing the type parameters (T and TResult) with the corresponding type arguments (int and string) in the declaration. I've also renamed it to avoid confusion:
string ExpandedFunc(int x)
In other words, Func<int, string> is a delegate which represents a function taking an int argument and returning a string.
Func<T, TResult> is often used in LINQ, both for projections and predicates (in the latter case, TResult is always bool). For example, you could use a Func<int, string> to project a sequence of integers into a sequence of strings. Lambda expressions are usually used in LINQ to create the relevant delegates:
Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);
foreach (string s in strings)
{
Console.WriteLine(s);
}
Result:
Value=3
Value=7
Value=10
A Func<int, string> eats ints and returns strings. So, what eats ints and returns strings? How about this ...
public string IntAsString( int i )
{
return i.ToString();
}
There, I just made up a function that eats ints and returns strings. How would I use it?
var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;
foreach( int i in lst )
{
str += IntAsString(i);
}
// str will be "12345"
Not very sexy, I know, but that's the simple idea that a lot of tricks are based upon. Now, let's use a Func instead.
Func<int, string> fnc = IntAsString;
foreach (int i in lst)
{
str += fnc(i);
}
// str will be "1234512345" assuming we have same str as before
Instead of calling IntAsString on each member, I created a reference to it called fnc (these references to methods are called delegates) and used that instead. (Remember fnc eats ints and returns strings).
This example is not very sexy, but a ton of the clever stuff you will see is based on the simple idea of functions, delegates and extension methods.
One of the best primers on this stuff I've seen is here. He's got a lot more real examples. :)
It is a delegate that takes one int as a parameter and returns a value of type string.
Here is an example of its usage:
using System;
class Program
{
static void Main()
{
Func<Int32, String> func = bar;
// now I have a delegate which
// I can invoke or pass to other
// methods.
func(1);
}
static String bar(Int32 value)
{
return value.ToString();
}
}
Func<int, string> accepts an int value parameter and returns a string value. Here's an example where an additional supporting method is unnecessary.
Func<int, string> GetDogMessage = dogAge =>
{
if (dogAge < 3) return "You have a puppy!";
if (dogAge < 7) return "Strong adult dog!";
return "Age is catching up with the dog!";
};
string youngDogMessage = GetDogMessage(2);
NOTE: The last object type in Func (i.e. "string" in this example) is the functions return type (i.e. not limited to primitives, but any object). Therefore, Func<int, bool, float> accepts int and bool value parameters, and returns a float value.
Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
{
if(intValue > 100 && boolValue) return 100;
return 1;
};
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);
HTH
Related
I am new to delegates. Today I saw a code on this Link. AS i am new to c# and specially to delegates, i was unable to understand the below code.
public static void Main()
{
Func<String, int, bool> predicate = (str, index) => str.Length == index;
String[] words = { "orange", "apple", "Article", "elephant", "star", "and" };
IEnumerable<String> aWords = words.Where(predicate).Select(str => str);
foreach (String word in aWords)
Console.WriteLine(word);
}
The OutPut of the above code is "star". AS predicate is expecting to parameters but in this case we are not passing any parameters. Your comments will be really appreciated.
So first, there's a function definition:
Func<String, int, bool> predicate = (str, index) => str.Length == index;
which reads as "given a string represented as str and an index represented as index return true if the length of the string is equal to the index otherwise false"
When you come across to the enumerable pipeline:
IEnumerable<String> aWords = words.Where(predicate).Select(str => str);
you pass this function definition above, which is similar to:
words.Where((element, index) => element.Length == index).Select(str => str);
and as you can see only the element "star" meets that criteria, i.e. the "star" has length 4 and its index is also 4.
In regard to your confusion of:
AS predicate is expecting to parameters but in this case we are not
passing any parameters.
Note that when it comes to LINQ, we only specify the "what" and the "how" is an implementation detail. so in the aforementioned code, the Where clause will pass each element and its index to the predicate function.
On another note, the Select is superfluous, just IEnumerable<String> aWords = words.Where(predicate) should shuffice.
Let's start to examine this code from the first line.
Func<String, int, bool> predicate = (str, index) => str.Length == index;
Here we have simply the declaration of a variable named predicate This is a particular kind of variable whose value is a function that receives two parameters of type string and int and it is expected to return a bool. But where is the body of that function? Just after the equals sign. The (str,index) are the parameters and the body is simply a comparison between the length of the parameter str with the value of the parameter index.
=> str.Length == index returns true if the condition matches otherwise returns false
Now that we understand the declaration of the delegate, the next question is where we use it. This is even simpler. We can use it whenever we need a function that matches our delegate.
Now there is an overload of Where IEnumerable extension that expects just that, so we can simply put the predicate variable in that place and call the Where extension
In short, the code just says, "Select all words where the length equals index"
string[] words = { "orange", "apple", "Article", "elephant", "star", "and" };
// select all words where the length equals the index
var aWords = words.Where((str, i) => str.Length == i);
foreach (var word in aWords)
Console.WriteLine(word);
Where<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)
Filters a sequence of values based on a predicate. Each element's
index is used in the logic of the predicate function.
Func<T1,T2,TResult> Delegate
Encapsulates a method that has two parameters and returns a value of
the type specified by the TResult parameter.
So the only magic is the Func
Func<String, int, bool> predicate = (str, index) => str.Length == index;
Which (in this case) is just a fancy way of writing
public bool DoSomething(string str, int index)
{
return str.Length == index;
}
In essence its just a delegate, unlike an Action its capable of returning a value
Delegates (C# Programming Guide)
A delegate is a type that represents references to methods with a
particular parameter list and return type. When you instantiate a
delegate, you can associate its instance with any method with a
compatible signature and return type. You can invoke (or call) the
method through the delegate instance.
To simplify it a bit,
var aWords = words.Where(str => str.Length == 4);
is the same as:
Func<string, bool> predicate = str => str.Length == 4;
var aWords = words.Where(predicate);
predicate() executes it, and predicate without () can be used to pass it as parameter to a method.
With local functions (functions that can be declared inside other functions) introduced in C# 7, it can be :
bool predicate(string str) { return str.Length == 4; }
var aWords = words.Where(predicate);
I'm using Dynamic Expresso for expression evaluation and works like a charm. Actually setting up custom functions, but seems like there is a something wrong with a method overload.
I've actually got two Round methods:
First one with one argument:
public static decimal Round(decimal userNumber)
{
return Math.Round(userNumber);
}
Second one with two arguments:
public static decimal Round(decimal userNumber, int decimals)
{
return Math.Round(userNumber, decimals);
}
Delegates got declared and Interpreter.SetFunction is called with no errors as well:
Func<decimal, decimal> roundFunction1 = (userNumber) => Round(userNumber);
Func<decimal, int, decimal> roundFunction2 = (userNumber, decimals) => Round(userNumber, decimals);
interpreter.SetFunction("ROUND", roundFunction1);
interpreter.SetFunction("ROUND", roundFunction2);
Variables are correctly passed and I've checked many times already that the parameter I'm passing is, in fact, a decimal.
The evaluation expression I pass, finally contains the following string, which has nothing wrong since the Interpreter.SetVariable(property.Key, property.Value) is inserting an "ImporteTotal" and a 666.66:
ROUND(ImporteTotal)
So, the exception I get when the evaluation gets done is:
Argument list incompatible with delegate expression (at index 0).
Note that I'm actually setting lots of functions which uses even DateTimes, int, strings and so on even combined, overloads as well! All of them work perfectly, but seems that deleting any of those overloads helps it working. In case both of them are "imported" on Dynamic Expresso, it complains.
Any ideas?
Many thanks.
UPDATE-EDIT:
I reviewed the UnitTesting Davide provided through pastebin and seems I got it failing.
This unit testing seems that is failing.
[Test]
public static void TestInterpreter()
{
var interpreter = new Interpreter();
Func<decimal, decimal> roundFunction1 = (userNumber) => Round(userNumber);
Func<decimal, int, decimal> roundFunction2 = (userNumber, decimals) => Round(userNumber, decimals);
Func<string, string, int> charindexFunction1 = (toFind, userString) => Charindex(toFind, userString);
Func<string, string, int, int> charindexFunction2 = (toFind, userString, offset) => Charindex(toFind, userString, offset);
interpreter.SetFunction("ROUND", roundFunction1);
interpreter.SetFunction("ROUND", roundFunction2);
interpreter.SetFunction("CHARINDEX", charindexFunction1);
interpreter.SetFunction("CHARINDEX", charindexFunction2);
var importe = 666.66M;
interpreter.SetVariable("ImporteTotal", importe);
var textoAlbaran = "ALBARAN-01";
interpreter.SetVariable("Albaran", textoAlbaran);
Assert.AreEqual(Round(importe), interpreter.Eval("ROUND(ImporteTotal)"));
Assert.AreEqual(Round(importe, 1), interpreter.Eval("ROUND(ImporteTotal, 1)"));
Assert.AreEqual(Charindex("BARAN", textoAlbaran), interpreter.Eval("CHARINDEX(\"BARAN\", Albaran"));
Assert.AreEqual(Charindex("BARAN", textoAlbaran, 2), interpreter.Eval("CHARINDEX(\"BARAN\", Albaran, 2)"));
}
public static decimal Round(decimal userNumber)
{
return Math.Round(userNumber);
}
public static decimal Round(decimal userNumber, int decimals)
{
return Math.Round(userNumber, decimals);
}
public static int Charindex(string toFind, string userString)
{
return userString.IndexOf(toFind);
}
public static int Charindex(string toFind, string userString, int offset)
{
return userString.IndexOf(toFind, offset);
}
Starting with DynamicExpresso 2.5.0, it's possible to register multiple methods with the same name (ie. overloads):
Func<decimal, decimal> roundFunction1 = (userNumber) => Math.Round(userNumber);
Func<decimal, int, decimal> roundFunction2 = (userNumber, decimals) => Math.Round(userNumber, decimals);
var interpreter = new Interpreter();
interpreter.SetFunction("ROUND", roundFunction1);
interpreter.SetFunction("ROUND", roundFunction2);
Assert.AreEqual(3.13M, interpreter.Eval("ROUND(3.12789M, 2)"));
Assert.AreEqual(3M, interpreter.Eval("ROUND(3.12789M)"));
I am developing a software that takes realtime-data and extracts a number of features from that depending on user input. Each available feature consists of one method that takes an array of doubles and return the wanted feature, such as this one for the MeanAbsoluteValue:
public static class MeanAbsoluteValue{
public static double Calculate(double[] data){
return data.Sum(s => Math.Abs(s)) / data.Length;
}
}
Since each of the features only has the one Calculate method I was thinking of trying to rewrite them so that they can be collected and chosen from that Collection.
I have tried writing an Interface for them to use, but since they are static this was not allowed.
Is there a way of doing this? And if so, could you point me in the right direction?
You can create an array of delegates constructed from the Calculate methods of these classes, like this:
Func<double[],double>[] array = new Func<double[],double>[] {
MeanAbsoluteValue.Calculate
, MeanValue.Calculate
, Deviation.Calculate
// ...and so on
};
Here is a demo on ideone.
Store delegates to your functions in a dictionary, and look them up by name
var methods = new Dictionary<string, Func<double[], double>>();
methods.Add("MeanAbsoluteValue", MeanAbsoluteValue.Calculate);
...
public double DoFunc(string name, double [] args)
{
var func = methods[name];
return func(args);
}
Just have a collection of Func...
var list = new List<Func<double[], double>(MeanAbsoluteValue.Calculate, Average.Calculate)
var accum = 0;
foreach(var func in list)
{
accum += func(new [] {1,3,4,});
}
Let's say a program like this:
class MyClass
{
public int Numbers;
public char Letters;
}
class Program
{
static void Main()
{
var mc = new MyClass[5];
for (var i = 0; i < 5; i++)
{
mc[i].Numbers = i + 1;
mc[i].Letters = (char) (i + 65);
}
}
}
Now, let's suppose an 'X' method that requires ALL the numbers contained in the object mc, in a separate array, that's sent as a parameter.
My first idea is a for, a new integers array, and copy one by one onto its respective position. But, what if the MyClass gets different, now it has strings and floats, and I wanna pull out the strings, now the for has to be completely redefined in its inside part to create the needed array for another 'X' method.
I know of cases where Linq helps a lot, for example, generics for Sum, Average, Count and another numeric functions, and of course, it's combination with lambda expressions.
I'm wondering if something similar exists to make the above arrays of MyClass (and anothers of course) in a faster-generic way?
If you want to use LINQ, you can do something like the following:
int [] numbers = mc.Select<MyClass, int>(m => mc.Number).ToArray();
To make it more generic than that, it gets a bit more complicated, and you may need reflection, or dynamic objects. A simple example with reflection would be:
private TValue[] ExtractFields<TClass, TValue>(TClass[] classObjs, string fieldName)
{
FieldInfo fInfo = typeof(TClass).GetField(fieldName, BindingFlags.Public | BindingFlags.Instance);
if (fInfo != null && fInfo.FieldType.Equals(typeof(TValue)))
return classObjs.Select<TClass, TValue>(c => (TValue)fInfo.GetValue(c)).ToArray();
else
throw new NotSupportedException("Unidentified field, or different field type");
}
And then just call it like:
int [] fields = ExtractField<MyClass, int>(mc, "Number");
If you are using C# 4.0, then you may use dynamic
class MyClass
{
public dynamic Numbers;
public char Letters;
}
EDIT: based on comments
I am not sure if this is what you want:
int[] arr = mc.Select(a => a.Numbers).ToArray<int>();
or without casting
int[] arr = mc.Select(a => a.Numbers).ToArray();
Why not just use Dictionary<int, char>, or if the data type is unknown then simply Dictionary<object, object>
If your goal is to generate a new array which is detached from the original array, but contains data copied from it, the most generic thing you could do would be to define a method like:
T my_array[]; // The array which holds the real things
U[] CopyAsConvertedArray<U>(Func<T,U> ConversionMethod);
That would allow one to generate a new array which extracts items from the original using any desired method.
Is there a way to set up a C# function to accept any number of parameters? For example, could you set up a function such that the following all work -
x = AddUp(2, 3)
x = AddUp(5, 7, 8, 2)
x = AddUp(43, 545, 23, 656, 23, 64, 234, 44)
Use a parameter array with the params modifier:
public static int AddUp(params int[] values)
{
int sum = 0;
foreach (int value in values)
{
sum += value;
}
return sum;
}
If you want to make sure there's at least one value (rather than a possibly empty array) then specify that separately:
public static int AddUp(int firstValue, params int[] values)
(Set sum to firstValue to start with in the implementation.)
Note that you should also check the array reference for nullity in the normal way. Within the method, the parameter is a perfectly ordinary array. The parameter array modifier only makes a difference when you call the method. Basically the compiler turns:
int x = AddUp(4, 5, 6);
into something like:
int[] tmp = new int[] { 4, 5, 6 };
int x = AddUp(tmp);
You can call it with a perfectly normal array though - so the latter syntax is valid in source code as well.
C# 4.0 also supports optional parameters, which could be useful in some other situations. See this article.
1.You can make overload functions.
SomeF(strin s){}
SomeF(string s, string s2){}
SomeF(string s1, string s2, string s3){}
More info: http://csharpindepth.com/Articles/General/Overloading.aspx
2.or you may create one function with params
SomeF( params string[] paramArray){}
SomeF("aa","bb", "cc", "dd", "ff"); // pass as many as you like
More info: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params
3.or you can use simple array
Main(string[] args){}