It is possible to create a Func object what references a generic method? like the LINQ OrderBy:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector
)
If I understand you correctly, you're asking if you can reference a generic method from within an anonymous method.
The answer is yes.
For example, suppose you want some Func that returns the elements of an IEnumerable<int> object in sorted order (precisely like OrderBy<int, int>). You could do this:
Func<IEnumerable<int>, Func<int, int>, IOrderedEnumerable<int>> orderByFunc =
System.Linq.Enumerable.OrderBy<int, int>;
Then you could use this Func just like any other:
int[] ints = new int[] { 1, 3, 5, 4, 7, 2, 6, 9, 8 };
// here you're really calling OrderBy<int, int> --
// you've just stored its address in a variable of type Func<...>
foreach (int i in orderByFunc(ints, x => x))
Console.WriteLine(i);
Output:
1
2
3
4
5
6
7
8
9
On the other hand, if you're asking whether it's possible to create a "generic anonymous method," like this:
Func<T> getDefault<T> = () => default(T);
Then it depends on your context. This can be done from within a context where T is already declared as a generic type parameter -- namely, within a generic class or generic method. (See Freddy Rios's answer.) Outside of such a context, unfortunately, it is illegal.
Yes, but it depends on the context - if you are already working with generics, just use the T in the context / if not, then you already know the specific type. In the later, if you need to reuse a bit of logic on a method, u probably already would benefit of moving that into a method, so just do like my second example below.
2 samples:
public T Something<T>() {
Func<T> someFunc = () => { return default(T); };
return someFunc();
}
public Func<T> GetDefaultCreator<T>() {
return () => { return default(T); };
}
Something like this?
Func<Nullable<int>, string> myFunc = c => c.HasValue ? c.ToString() : "null";
That successfully compiles, and you could assign any function to that that takes in a Nullable and returns a string.
I have done something like this:
public static class Helper{
public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection Form)
{
return Form.AllKeys.Cast<string>()
.Select(key => new KeyValuePair<string, string>(key, Form[key]));
}
}
Where this method has become an extension method to the request.form in C# web development.
I think I get it: Given the function static TResult DoSomeStuff<T, TResult>(T obj), can you create a Func<T, TResult> such that it will reference the function above, with no type parameters given at the creation of the reference to it.
I think this could work (You're welcome to test it, I have no C# near me at the moment):
class UselessClass<T, TResult>
{
// If it's a static method, this is fine:
public Func<T, TResult> DaFunc = RelevantClass.DoSomeStuff<T, TResult>;
// If not, something like this is needed:
public UselessClass(SomeClassWhereTheFunctionIs from)
{
DaFunc = from.DoSomeStuff<T, TResult>;
}
}
Also, in OrderBy, it's not actually a generic delegate. It's a declaration of a variable. When the function is given to it, the types are inferred from it.
Yes it's possible but you'll need to specify the type argument(s)
func<int> f = myClass.returnsT<int>;
where
class myClass
{
T returnsT<T>()
{...}
}
it Will not work without the type arguments
Related
I have read about Func<>, which says it iss a delegate and you can use it like for example:
Func<class,bool>
means you send a class or anything and get a bool result, this is what I got!
but what does the following mean?
Func<Class, bool> predicate
I have no idea, can you make it clear for me?
The former will not compile since class is a registered keyword and can only be used for class definitions.
The latter is a Func<T, TResult> which is a function that takes a parameter of type T and returns an object of type TResult. So in your case, the function takes an object of type Class and returns a bool.
The naming of Class is unfortunate but it’s actually allowed to use that identifier for a type. The following would be an example that takes such an object of type Class and then checks a property of it, returning true or false depending on the success of the comparison.
Func<Class,bool> predicate = obj => obj.Prop == "Foo";
var x = new Class();
x.Prop = "Foo";
Console.WriteLine(predicate(x)); // true
// with the following class definition
public class Class
{
public string Prop { get; set; }
}
A Func<> object is callable, just like methods, so we can use parentheses to call it and pass the object here. This would be equivalent to a method like this:
public bool predicate(Class obj)
{
return obj.Prop == "Foo";
}
But the usual way to use Func<> is using lambda expressions to be able to create functions quickly inline. This is very commonly used in LINQ where you use lambda expressions, and as such Func<> objects, all the time:
var filtered = listOfOjects.Where(obj => obj.Prop == "Foo").ToList();
// ^^^^^^^^^^^^^^^^^^^^^^^^
// this is the predicate function from above
// so you could also pass the predicate Func from above:
var filtered = listOfObjects.Where(predicate).ToList()
Func<MyClass,bool> is a delegate type
In Func<MyClass, bool> predicate , predicate is a delegate variable.
You would normally see something like
Func<MyClass, bool> predicate = c => c.IsValid;
...
if (predicate(myClass1)) DoSomething();
That's just how you instantiate the Func. Compare to a string:
string str;
If you want to instantiate and assign it at the same time, you do something like this:
Func<string, bool> isLongerThanThree = input => input.Length > 3;
isLongerThanThree("string"); // Returns "true"
Are you referring to the word predicate?
That's just the name of a parameter. Notice the similarity:
MyMethod(int myAge)
MyMethod(List<bool> myBooleans)
MyMethod(Func<Class,bool> myPredicate)
Also notice the similarities between:
int myAge = 30;
myAge is a variable of type int who has been given the value of 30.
Func<Class,bool> myPredicate = (x => x.IsAlive);
myPredicate is a variable of type Func<Class,bool> who has been given the value of (x => x.IsAlive).
Func<> is a delegate which represents a method which return a result. C# provides signatures for up to 15 input arguments, which should be enough to represent all possible methods you will ever need :)
it is hardly event to imagine method which has 15 input arguments. Beside Func<> there are also some special version of the delegate like Predicate<T> which is nothing else that Func<in T, bool TResult> or Action<> which represent a function without return value, return value is void.
Delegates(C# Programming Guide)
You can assign any method, static or instance or even anonymous with the matching signature to the Func<>. For example:
Func<MyClass, bool> predicate = (myClass) => {return true;} //anonymoys method
public class MyClass
{
public bool MyPredicate(MyClass myClass)
{
return true;
}
public static bool MyStaticPredicate(MyClass myClass)
{
return true;
}
}
Func<MyClass, bool> predicate = new MyClass().MyPredicate;
Func<MyClass, bool> staticPredicate = MyClass.MyStaticPredicate;
I am trying to define a valid input for my method Pairwise. Pairwise takes an argument IEnumerable which I am having trouble figuring out what is exactly. I have tried alot of stuff but can never really get there.
public delegate void PairwiseDel(Type left, Type right);
public static void Pairwise(IEnumerable<Type> col, PairwiseDel del)
{
// stuff happens here which passes pairs from col to del
}
can someone plz tell and illustrate what a valid input for my method would be?
IEnumerable<T> is a very important interface in .NET library. It represents an abstraction describing a sequence of elements of type T.
This generic interface has multiple implementations:
Built-in 1-dimension arrays T[] implement IEnumerable<T>
All generic .NET collections implement IEnumerable<T>
Methods that use yield return produce IEnumerable<T>
Multiple methods in .NET LINQ library both take and return IEnumerable<T>
If you would like to test your method, pass it an array Type[]:
var items = new Type[] { typeof(int), typeof(string), typeof(long) };
Pairwise(items, (a, b) => {
Console.WriteLine("A={0}, B={1}", a.Name, b.Name);
});
This would be a valid input:
var collection = new List<Type>();
collection.Add(typeof(string));
collection.Add(typeof(int));
PairWise(collection, YourDelegateHere);
I'm implementing a fluent argument assertion library where the focus is in strong type checking on compile time. Intellisense should only show methods and extensions available for the asserted type.
I'm having problems resolving proper type arguments when creating an extension for IEnumerable.
Idea in the library is that you can call ThrowIf (or ThrowIfNot) on any type which will return you an assertion instance of type IAssertion:
public static IAssertion<T> ThrowIf<T>(this T t)
{
return new IfAssertion<T>(t);
}
Now I want to check against IEnumerable if it contains a specific item. There will be two overloads where one takes the object of type T as a parameter and the other takes a function where to do the evaluation:
public static T1 Contains<T1, T2>(this IAssertion<T1> assertion, T2 item)
where T1 : IEnumerable<T2>
{
// assertion logic
return assertion.Value;
}
public static T1 Contains<T1, T2>(this IAssertion<T1> assertion, Func<T2, bool> func)
where T1 : IEnumerable<T2>
{
// assertion logic
return assertion.Value;
}
Everything goes fine when using the overload taking an instance of the actual type. But the latter one with the function compiler cannot infer the type arguments properly unless cast is made:
var list = new List<string>();
list.ThrowIf().Contains("foo"); // compiles
list.ThrowIf().Contains((string s) => false); // compiles
list.ThrowIf().Contains(s => false); // does not compile
Is there any way I could make the compiler happy without doing the cast for the function parameter?
More implementation details can be found from here:
https://bitbucket.org/mikalkai/argument-assertions/overview
Disclaimer: This answer is only valid if IAssertion can be made covariant.
Assuming that IAssertion is covariant, you don't necessarily need two generic type parameters T1 and T2 for the Contains methods. Instead, you specify IEnumerable in your interface directly and use only one generic type parameter like this:
public static IEnumerable<T> Contains<T>(this IAssertion<IEnumerable<T>> assertion, T item)
{
// assertion logic
return assertion.Value;
}
public static IEnumerable<T> Contains<T>(this IAssertion<IEnumerable<T>> assertion, Func<T, bool> func)
{
// assertion logic
return assertion.Value;
}
Then you can use the contains method like this:
var list = new List<string>();
list.ThrowIf().Contains("foo"); // compiles
list.ThrowIf().Contains((string s) => false); // compiles
list.ThrowIf().Contains(s => false); // compiles now too
This question already has an answer here:
Generic type parameter and Nullable method overload
(1 answer)
Closed 7 years ago.
The following pair of functions attempt to replicate the null conditional operator available in C# 6.0:
public static TResult Bind<T, TResult>(this T obj, Func<T, TResult> func)
where T : class
{
return obj == null ? default(TResult) : func(obj);
}
public static TResult Bind<T, TResult>(this Nullable<T> obj, Func<T, TResult> func)
where T : struct
{
return obj.HasValue ? func(obj.Value) : default(TResult);
}
The first function is constrained to classes and for a String s allows me to write something like:
var x = s.Bind(a => a.Substring(1));
The second function is where I am running into trouble. For example, given a int? number I would like to write:
var y = number.Bind(a => a + 1);
However, this gives me the following error:
The call is ambiguous between the following methods or properties: 'BindingExtensions.Bind<T, TResult>(T, Func<T, TResult>)' and 'BindingExtensions.Bind<T, TResult>(T?, Func<T, TResult>)'
I'm guessing that this has something to do with the interplay between the type inference of the anonymous function and the method overload resolution. If I specify the type of a as int than it compiles just fine.
var y = number.Bind((int a) => a + 1);
However, this is clearly less than desirable. Can anyone tell me why the compiler thinks the above call to bind is ambiguous and/or offer a way to fix this? I know I could simply name the two functions differently, but what fun is that?
Overloaded functions cannot be disambiguated by type constraints (see "Generic constraints, where T : struct and where T : class"). Any nullable type N satisfies N : T and N : Nullable<T>, required by the former and latter Bind definitions respectively. I am guessing that number is of type Nullable<int> or similar.
var x = s.Bind(a => a.Substring(1));
This is unambiguous because s is of type string and for all T not string : Nullable<T>, so only the first overload is acceptable.
var y = number.Bind(a => a + 1);
This is ambiguous because the type of a => a + 1 may be inferred as either Func<int?,int?> or Func<int,int>. If inferred as Func<int?,int?> the first overload applies, and if inferred as Func<int,int> the second overload applies.
var y = number.Bind((int a) => a + 1);
This is unambiguous if number is of type Nullable<int>, for example. For the first overload for all T not T : Nullable<int> and T : int, so it does not apply. For the second overload you just need T : int which is easily satisfied by T = int.
Try this:
public static TResult Bind<T, TResult>(this T? obj, Func<T?, TResult> func)
where T : struct
{
return obj.HasValue ? func(obj.Value) : default(TResult);
}
Let's suppose I have defined Func as follows:
Func<MyClass, object> f = o => o.StringProperty;
or
Func<MyClass, object> f = o => o.Property.SomeMethod();
Is there way to get the actual return type without specifically calling it?
You can get the return type like this:
f.Method.ReturnType
But this will return you the type object. If you want to get Method or String or something that derives from object, you won't be able to have the information unless you call the method.
Actually you could, but this would mean that you'd have to dissassemble the method core and then analyze it to see what the method can return. But even then, there might be many different return types.
So the answer is: if you want to know that it returns an object, then yes you can, otherwise it's not worth the trouble, and it's better to find another way of doing what you need.
Since you are retrieving these Func<MyClass, object> delegates at runtime from other sources, the type information is essentially lost.
Instead, where these functions are defined, you can have the callers essentially encode that type information in a wrapped delegate by taking advantage of the LINQ Expression API (EDIT: Silly me, far more simpler at this point; we already have the generic compile time information):
public class MyClassDelegate
{
private readonly Func<MyClass, object> Function;
public Type ReturnType { get; private set; }
private MyClassDelegate(Func<MyClass, object> function, Type returnType)
{
this.Function = function;
this.ReturnType = returnType;
}
public object Invoke(MyClass context)
{
return Function(context);
}
public static MyClassDelegate Create<TReturnType>(Func<MyClass, TReturnType> function)
{
Func<MyClass, object> nonTypedFunction = o => function(o);
return new MyClassDelegate(nonTypedFunction, typeof(TReturnType));
}
}
(A derived generic MyClassDelegate<TReturnType> : MyClassDelegate class could be made as well to get around some of the sillyness in the Create method, or avoid value-type boxing, or to have the return type information available at compile time or even by reflecting on whatever MyClassDelegate<TReturnType> is.)
Callers defining the delegates instead of working directly with a Func<MyClass, object> would instead work with this class and define their delegates as:
MyClassDelegate f1 = MyClassDelegate.Create(o => o.StringProperty);
MyClassDelegate f2 = MyClassDelegate.Create(o => o.Property.SomeMethod());
Your API would require a MyClassDelegate, with which you can easily access their types:
Console.WriteLine(f1.ReturnType.FullName); //string
Console.WriteLine(f2.ReturnType.FullName); //whatever `SomeMethod()` is declared to return
Finally, you can invoke the delegates or even create Func<MyClass, object> delegates still:
f1.Invoke(myClassInstance);
Func<MyClass, object> f3 = f1.Invoke;
You can do something close to this by using a generic method to make the compiler infer the type arguments:
static Func<T1, R> Infer<T1, R>(Func<T1, R> f) { return f; }
And then:
var func = Infer((string s) => s.Length);
This will encode the return type into the type of func at compilation time.
Of course for a more generally applicable solution you would need a bunch of overloads of Infer to cover Action and Func with one, two, three, etc arguments.
If you then want to get the return type at runtime, for any kind of Func it's as simple as func.Method.ReturnType as ppetrov has already pointed out.