Generic Methods in C# - c#

Generic Methods in general are new to me. Need a method that returns a Collection of a generic type, but also takes a collection of the same generic type and takes
Expression<Func<GenericType, DateTime?>>[] Dates
parameter. T throughout the following function should be the same type, so right now I was using (simplified version):
private static Collection<T> SortCollection<T>(Collection<T> SortList, Expression<Func<T, DateTime>>[] OrderByDateTime)
{
return SortList.OrderBy(OrderByDateTime[0]);
}
but i'm receiving error:
Error: The type arguments for method
'System.Linq.Enumerable.OrderBy(System.Collections.Generic.IEnumberable,
System.Func)' cannot be
inferred from the usage. Try
specifying the type arguments
explicitly.
Is there anyway to do this?

Sorry for answering twice, but this is legitimately another solution.
You're passing in an Expression<Func<T, DateTime>> but Orderby wants a Func<T, DateTime>
You can either compile the expression:
return new Collection<T>(SortList.OrderBy(OrderByDateTime[0].Compile()).ToList());
or pass in straight out funcs as arguments:
private static Collection<T> SortCollection<T>(Collection<T> SortList, Func<T, DateTime>[] OrderByDateTime)
{
return new Collection<T>(SortList.OrderBy(OrderByDateTime[0]).ToList());
}
I'd recommend reading up on Expressions on msdn

In this situation, the compiler is failing to figure out what type arguments you intend to provide to the OrderBy method, so you'll have to supply them explicitly:
SortList.OrderBy<T, DateTime>(OrderByDateTime[0])
You'll probably want to call ToList() if you want a Collection to be returned

Related

Invoke ToList() method using reflection at runtime in C#

I have a generic as follows.
public class PaginatedList<T> : List<T>
{...}
I simply want to invoke ToList() method on that object at runtime using reflection.
Can someone please help.
I have come so only far.
MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList");
var constructedToList = toListMethod.MakeGenericMethod(TypeObjectOfT);
constructedToList.Invoke(paginatedListObject, null);
I get exception at the last line with message, Parameter count mismatch. I feel that the first two steps are ok, as I have checked the toListMethod.ToString() and constructedToList.ToString(). And they have given me the following output, which I feel is correct.
System.Collections.Generic.List`1[TSource] ToList[TSource](System.Collections.Generic.IEnumerable`1[TSource])
System.Collections.Generic.List`1[AvbhHis.BL.Entities.PatientCategory] ToList[PatientCategory](System.Collections.Generic.IEnumerable`1[AvbhHis.BL.Entities.PatientCategory])
Questions:
1. Am I right so far?
What should be the parameter to MakeGenericMethod() method. In my case it is the Type of intance of the object of Type T at runtime.
There seems to be some problem with the Invoke method call. Is passing null correct as second parameter? The first parameter should be an object of the type PaginatedList right?
My energy is out, so kindly help.
The first parameter [to Invoke] should be an object of the type PaginatedList right?
ToList is a static method on Enumerable that takes an IEnumerable<T> as it's only parameter:
public static List<TSource> ToList<TSource>(
this IEnumerable<TSource> source
)
Invoke takes the instance as the first parameter and the method parameters after that. For a static method you use null for the "instance" parameter.
So the proper syntax would be
object o = constructedToList.Invoke(null, new object[] {paginatedListObject});
o will then be an object of type List<T> (but you don't know kniw what T is at compile time, so you can't cast it).
List<T> has a constructor that takes an IEnumerable<T> (Which gets called in ToList) so you can simplyfy this task by writing the following:
var resul = Activator.CreateInstance(typeof(List<>).MakeGenericType(TypeObjectOfT), paginatedListObject);

Why can you not use anon function with a dynamic parameter?

Just ran into this today
An anonymous function or method group cannot be used as a constituent
value of a dynamically bound operation.
when trying to do
static R ifNotNull<R>(dynamic o, Func<dynamic, R> returnFunc, R otherwise) {
return ReferenceEquals(null, o) ? otherwise : returnFunc(o);
}
and use it with
dynamic firstAddress = ...;
return ifNotNull<string>(firstAddress, (a) => a.address_1, null)
Now most of the limitations on dynamics make sense to me - you can't use an extension method because how is the compiler supposed to decide which static to compile it to? But I don't get this here. Where does the confusion come in? What exactly is the limitation?
What is the static type of the lamba a => a.address_1? You may be tempted to say it's a Func<dynamic, dynamic>. But remember:
A lambda expression is an anonymous function that you can use to
create delegates or expression tree types.
So maybe it's an Expression<Func<dynamic, dynamic>>. A lamda by itself doesn't have a single static type.
Now normally type inference would figure out that you're passing the lamba to a function that takes a Func and it will be converted to a delegate at compile time. However when you are calling with dynamic arguments the method call is dispatched dynamically.
If you have a method call with a dynamic argument, it is dispatched
dynamically, period. During the runtime binding, all the static types
of your arguments are known (emphasis mine), and types are picked for the dynamic
arguments based on their actual values.
So the fact that your method takes a Func isn't take into account, since the actual method call isn't determined until runtime so there is no type inference.
To get this to compile you'll have to cast your lamba to a Func<dynamic, string> as below:
return ifNotNull<string>(firstAddress, new Func<dynamic, string>((a) => a.address_1), null);
Now the static type of your lamda is known.
I meant that you need to cast the lambda method to the expect expression you want. Then it'll work just fine.
Like this:
return ifNotNull(firstAddress, (Func<dynamic, string>)((a) => a.address_1), null);

how to use a function as parameter in extension method?

I have read that is recomended to use functions instead of predicates in the extension methods, so I am trying to do it.
public static void Insert<T>(this ObservableCollection<T> paramOC, T NewElement, Func<T, T, bool> condition)
{
//code
}
I am trying to use in this way:
myOC.Insert(myNewElement, e=>e.Name.CompareTo(myNewElement.Name) > 0));
But I get an error that says that the delete System.Func does not take 1 argument.
However, if I use a predicate intead of the function, it works.
What am I missing?
thank so much.
You need Func<T,bool> (which takes one argument and returns bool), not Func<T,T,bool>
Predicate<T> works because it takes one argument and returns bool, so it matches with the lambda expression.Func<T,T,bool> expects two arguments and returns bool which doesn't match with your expression hence the error.
Your Func<T,T,bool> takes 2 parameters and returns bool
You have two choise
as Selman22 says change it to Func<T,bool>
call it as (e1,e2) => ..

Can someone please explain the <Func<T, bool>> in a simple way for me

I am looking at code containing:
public virtual ICollection<T> GetPk(string pk)
{
Expression<Func<T, bool>> predicate = c => c.PartitionKey == pk;
return this.GetAll(predicate);
}
Can someone explain the syntax of <Func<T, bool>> ?
Simply Func<T, bool> is the anonymous method signature. The first type T is the input parameter type and the second type is the return type. This is more like a method when you consider your representation:
bool AnonMethod(T arg0)
{
return arg0.PartitionKey == pk;
}
One of the best explanation can be found at MSDN
You can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate. This means that the encapsulated method must have one parameter that is passed to it by value, and that it must return a value.
As for argument in your example T is the type of input parameter and bool is the return type of exacted method.
A Func<T, bool> represents a function that takes an object of type T and returns a bool. It's commonly referred to as a "predicate", and is used to verify a condition on an object.
An Expression<Func<T, bool>> represents the abstract syntax tree of the function, i.e. its syntactic structure. It can be used to analyse the code of the function for various purposes, such as transforming it to SQL to be executed against a database.
I always find MSDN to be worth checking on things like this first,
http://msdn.microsoft.com/en-us/library/bb549151.aspx
Beaten by Maheep, didn't see the post message pop-in.
Basically, you're declaring a method that matches a signature, that can then be passed in to the call to get the data.
It is confusing at first but Func<T, bool> describes a function that returns a bool and accepts a parameter as type T.
In this case, T is an object that has a PartitionKey property and this GetPk method is using the Func<T, bool> to match all the T items in the instance object which have a PartitionKey that matches the string pk.
For some background; prior to Func<T, TResult> (and the rest of this family) being part of the framework, you either had to explicitly define delegates or use anonymous methods.
Func and Action were added as part of the addition of lambda expressions to the language. They are the framework-defined delegates which lambda expressions are typed as, but which you as a developer can also use in place of your own custom delegate definitions.
You can get a nice history here;
http://blogs.msdn.com/b/ericwhite/archive/2006/10/03/lambda-expressions.aspx
It's additional syntax so you know what goes in and out of the function.
Func<T, bool> means:
function has 1 input T and 1 output that's bool.
This is other variations of the function

Defining a lambda expression with an anonymous type contained within that lambda

I'm trying to avoid a dynamic type in my lambda expression for grouping a collection. The type is defined anonymously at compile time (and unambiguously as far as I can tell). I'd rather not define the type as a full-fledged class as I'm only using it a few times in this single method.
Sample code:
Func<MyData, dynamic> dataGrouping = md => new
{
md.Property1,
md.Property2,
md.Property3
};
var groupedData = myDataCollection.GroupBy(dataGrouping);
While this will compile, it leaves me with no intellisense or strong typing inside the group as the type is dynamic.
I can't specify the type of dataGrouping as var, because I'm in C# and I get complaints of Cannot assign lambda expression to implicitly typed local variable.
Could I replace dynamic with the result of GetType() on the anonymous type? I'd then need the type before it's used in the lambda, but I can't see a useful way to get a handle on it before I'm already into the lambda itself.
Is there an elegant way of getting the type of this anonymous class?
Is there any reason you don't want to put the lambda expression directly in the GroupBy call? That's the way it all usually hangs together:
var groupedData = myDataCollection.GroupBy(md => new
{
md.Property1,
md.Property2,
md.Property3
});
You could make this work with an extra method:
static Func<TSource, TResult> CreateFunction<TSource, TResult>
(Func<TSource, TResult> function)
{
return function;
}
and then use type inference:
var dataGrouping = CreateFunction((MyData md) => new
{
md.Property1,
md.Property2,
md.Property3
});
Note how I've explicitly typed the parameter so that type inference has something to work with. That will work, but it's a bit ugly. I would embed the lambda expression directly in the method call unless you have any particular reason not to.

Categories

Resources