Passing var as T parameter - c#

I am trying to build OrderBy expression the problem is when I pass var object to TSource the Type for TSource will be object not the Actual Column type
for example the Actual type is int but TSource type is object.
Type tblType = tblObj.GetType();
PropertyInfo propinfo;
propinfo = tblType.GetProperty(ColumnName);
if (propinfo == null)
{
return null;
}
var instance = Activator.CreateInstance(propinfo.PropertyType);
result = result.OrderBy(GetOrder(item.ColumnName, tblObj, instance));
and here is the lambda expression builder
public Expression<Func<T, TSource>> GetOrder<T,TSource>(string field, T item,TSource source)
{
if (string.IsNullOrEmpty(field))
{
return null;
}
var param = Expression.Parameter(typeof(T), "c");
Expression conversion = Expression.Convert(Expression.Property
(param, field), typeof(TSource));
return Expression.Lambda<Func<T, TSource>>(conversion, param);
}

When not sure of the type, you can use dynamic so the type will be found at runtime level.
result = Enumerable.OrderBy(
result,
GetOrder(item.ColumnName, tblObj, (dynamic)instance));

You either must use dynamic keyword or use reflection.
But, you can solve your probelm with dynamic more easily.
The only problem is that, extension methods will not be dynamically dispatched.
So, you must call extension method as simple static method:
result = Enumerable.OrderBy(
result,
GetOrder(item.ColumnName, tblObj, instance as dynamic));
Also, you can ask a question "Why extension methods can not be dynamically dispatched?"
The asnwer by #EricLippert:
That means that in order to get a dynamic extension method invocation
resolved correctly, somehow the DLR has to know at runtime what all
the namespace nestings and "using" directives were in your source
code. We do not have a mechanism handy for encoding all that
information into the call site. We considered inventing such a
mechanism, but decided that it was too high cost and produced too much
schedule risk to be worth it.
So, CLR must find the namespace which holds extension method. CLR searches this and it it finds the method namespace, then it just changes for example, result.OrderBy to Enumerable.OrderBy(result, ...). But, in case of dynamic keyword, DLR(Dynamic Language Runtime) must find the class of this method in runtime, again based on included namespaces. Microsoft team rightly thinks that it is too high cost and avoids to implement it.

Method Activator.CreateInstance(Type type) returns object, not int.
May be you should unbox it to int before use;

Follow the documentation Activator.CreateInstance return object, so you have to cast it to destination type or you can use dynamic type, but than compiler can't check types.

Related

Difference between Task.FromResult<TResult> vs Task.FromResult? [duplicate]

So, I ran across an answer by Servy ( https://stackoverflow.com/a/15098242/496680 ) and some of his code does this:
public static int BinarySearch<TSource, TKey>(...)
for an extension method, but he calls it like this:
arr.BinarySearch(...)
I asked around and somebody metioned that its an implied generic type parameter.
I googled them but found no information on them.
I understand how generics work but I'm failing to understand how/when to use these.
Why does servy use them in his extention method?
Is there a more official name for these that I can search for?
Well, you left out the most important part that makes it all work. The type parameters can be inferred by the actual object parameters passed in.
For instance:
static class Extensions {
internal static IEnumerable<U> Test<T, U>(
this IEnumerable<T> items,
Func<T, U> converter) {
foreach (T item in items) {
yield return converter(item);
}
}
}
This extension method works on any IEnumerable class and will convert each item in the enumeration to another type based on the converter you provided. This is standard generics.
Now, there are many ways to call this method:
IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");
// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);
// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);
// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);
// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);
All four variations call the same method and return the same result. Type inference works by looking at the parameters passed and automatically inferring their types based on what's being provided. In our examples above, it's able to determine that type T is of type int because we passed in an IEnumerable<int> into the parameter for IEnumerable<T>. It is also able to infer that type U is of type string because we passed in a Func matching the initial type of T with int and returning a string. So the Func<T, U> is filled in with our converter function of Func<int, string>.
From the inference above, it's a standard generic method at that point. Type inference and extension methods are nothing more than convenience/syntactic sugar. In fact, if you decompile the output you can see that extension methods are replaced with static calls and are usually defined with the type parameters explicitly filled out. (This varies based on your decompiler and the set options).
He uses a generic method in this case because it allows his method to work with any type contained within a Collection<T>. The generic method makes this very flexible, and usable for any type. He uses the type inferrence when calling the method because it simplifies the code at the call site.
The automatic handling is called Type Inferrence, and is covered, in detail, in the C# Language Specification, section 7.5.2: Type Inferrence. If you want to understand it in detail, I would recommend downloading the C# language specification.
The term I usually hear is 'type inference'.

When passing dynamic to method, the result is dynamic expression, even if it is not

In C# 5 when I tried to pass a dynamic as a method parameter the result for some reason became dynamic.
class Program
{
static void Main(string[] args)
{
dynamic value = "John";
Find<int>(value).ToList();
}
public static IEnumerable<T> Find<T>(object value)
{
//SOME LOGIC
yield return default(T); //REAL RESULT
}
}
Find<T>(value) has to return IEnumerable<T>. Why compiler thinks it is dynamic?
I know that Find<int>(val as object).ToList(); solves this, but I want to understand WHY it happens.
Because there could be a Find that matches another method than your Find at runtime, once you go dynamic, everything is dynamic, including resolving which method fits, so as soon as something is dynamic in an expression, the whole expression is dynamic.
For example there could be another method like
public static T Find<T>(sometype value)
{
return default T;
}
This would be a better match at runtime if the dynamic was actually of type sometype, so as long as the compiler doesn't know what dynamic is it can't infer the return type since that type could be anything returned by the method that matches best AT RUNTIME.
So the compiler says it returns dynamic because that's it best bet, your method returns something else, but the compiler doesn't know yet if that method will be the one called.
dynamic is type unknown at compile time but in the runtime. So in the runtime it can be a string type and there could be a better match called Find(string value) which returns a different type. That's the reason the compiler is unable to tell you. It is resolved at runtime.

What are implied generic type parameters

So, I ran across an answer by Servy ( https://stackoverflow.com/a/15098242/496680 ) and some of his code does this:
public static int BinarySearch<TSource, TKey>(...)
for an extension method, but he calls it like this:
arr.BinarySearch(...)
I asked around and somebody metioned that its an implied generic type parameter.
I googled them but found no information on them.
I understand how generics work but I'm failing to understand how/when to use these.
Why does servy use them in his extention method?
Is there a more official name for these that I can search for?
Well, you left out the most important part that makes it all work. The type parameters can be inferred by the actual object parameters passed in.
For instance:
static class Extensions {
internal static IEnumerable<U> Test<T, U>(
this IEnumerable<T> items,
Func<T, U> converter) {
foreach (T item in items) {
yield return converter(item);
}
}
}
This extension method works on any IEnumerable class and will convert each item in the enumeration to another type based on the converter you provided. This is standard generics.
Now, there are many ways to call this method:
IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");
// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);
// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);
// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);
// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);
All four variations call the same method and return the same result. Type inference works by looking at the parameters passed and automatically inferring their types based on what's being provided. In our examples above, it's able to determine that type T is of type int because we passed in an IEnumerable<int> into the parameter for IEnumerable<T>. It is also able to infer that type U is of type string because we passed in a Func matching the initial type of T with int and returning a string. So the Func<T, U> is filled in with our converter function of Func<int, string>.
From the inference above, it's a standard generic method at that point. Type inference and extension methods are nothing more than convenience/syntactic sugar. In fact, if you decompile the output you can see that extension methods are replaced with static calls and are usually defined with the type parameters explicitly filled out. (This varies based on your decompiler and the set options).
He uses a generic method in this case because it allows his method to work with any type contained within a Collection<T>. The generic method makes this very flexible, and usable for any type. He uses the type inferrence when calling the method because it simplifies the code at the call site.
The automatic handling is called Type Inferrence, and is covered, in detail, in the C# Language Specification, section 7.5.2: Type Inferrence. If you want to understand it in detail, I would recommend downloading the C# language specification.
The term I usually hear is 'type inference'.

Why VS2010 IntelliSense fails when chaining methods with dynamic args

I would like some explanation of you experts in C# 4.0 dynamic.
I have a fluent builder class to help configure an object before creating it. This interface has a method SetParameters(...):
public FluentBuilder<TInterface> SetParameters(dynamic parameters)
{
_parameters = parameters;
return this;
}
I'm doing this to consume the fluent interface:
var order = new Order();
/* Setting up parameters */
dynamic parameters = new ExpandoObject();
parameters.Transaction = transactionObj;
parameters.CurrentPrincipal = Thread.CurrentPrincipal;
var proxiedOrder = ObjectProxyFactory
.Configure<IOrder>(order)
.FilterMethods(o => o.InsertOrder())
.AddPreDecoration(AppConcerns.JoinSqlTransaction)
.AddPreDecoration(AppConcerns.EnterLog)
.AddPostDecoration(AppConcerns.ExitLog)
.AddPostDecoration(AppConcerns.SecurityCheck)
.SetParameters(parameters)
.Teste() //this method doesn't exist in the fluent builder
.CreateProxy();
var result = proxiedOrder.InsertOrder();
As commented in the above snippet, the method called Teste() doesn't exists in the fluent interface, but intelissense allow write anymethod after I call SetParameters like it returning dynamic, but as you see in code, SetParameters returns FluentInterface that is not dynamic.
The code above compiles sucessfully by in runtime will fail because in runtime the method Teste() will not be found in FluentBuilder class.
To resolve this problem in design-time, and to get correct Intelissense, I need to cast the parameter to the ExpandoObject class:
var proxiedOrder = ObjectProxyFactory
.Configure<IOrder>(order)
.FilterMethods(o => o.InsertOrder())
.AddPreDecoration(AppConcerns.JoinSqlTransaction)
.AddPreDecoration(AppConcerns.EnterLog)
.AddPostDecoration(AppConcerns.ExitLog)
.AddPostDecoration(AppConcerns.SecurityCheck)
.SetParameters((ExpandoObject)parameters) //cast to ExpandoObject
.Teste() //now intelissense is giving me an "red" error and solution will not compile
.CreateProxy();
var result = proxiedOrder.InsertOrder();
I've found that, anytime I pass a C# dynamic parameter in any method chaining, after that method receiving the dynamic parameter, the subsequent calls to methods will behave like returning a C# dynamic object, even if the return type of the method it's not dynamic.
Is it a bug ? Or is this expected to happens ?
It's expected to happen. Any method call involving a dynamic argument is resolved dynamically - the exact overload can't be determined until execution time, so the return type is unknown at compile time, so it's treated as being dynamic. In some cases the C# compiler could infer more information (e.g. if it's a static method call) but for simplicity it doesn't. Only a variable few expressions involving dynamic values have non-dynamic types. (From memory, the is operator is always bool, and a constructor is always assumed to return the type being constructed.)
EDIT: I've finally found the spec reference. From section 7.6.5:
An invocation-expression is dynamically bound (ยง7.2.2) if at least one of the following holds:
The primary-expression has compile-time type dynamic.
At least one argument of the optional argument-list has compile-time type dynamic and the primary-expression does not have a delegate type.
In this case the compiler classifies the invocation-expression as a value of type dynamic.

Enumerable.Where - How To Read The API

I am trying to understand specifically why it is neccessary to have this Where<TSource>
What does the type straight after Where tell you?
I understand the 'this' concept which means its an extension method but cannoth understand the type after Where
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
Func<TSource, bool> is a pointer to a function which takes TSource as parameter and returns boolean. For example if you had the following function:
public bool Foo(SomeType abc)
{
return abc.SomeProperty == "123";
}
you could pass it as argument to the Where method if you had a list of SomeType:
SomeType[] values = ...
var result = values.Where(Foo);
You could also use an anonymous function which avoids you the need to declare another function explicitly:
SomeType[] values = ...
var result = values.Where(x => x.SomeProperty == "123");
UPDATE:
I seem to have misunderstood the question. The type after the name of the function Where<TSource> indicates a generic function definition. It indicates that this function has a generic argument which can be of any type. So for example when you write:
SomeType[] values = ...
var result = values.Where(x => x.SomeProperty == "123");
TSource equals SomeType and the compiler is capable of automatically inferring it from the delegate. You could specify it explicitly but it's too much of a writing:
SomeType[] values = ...
IEnumerable<SomeType> result = values.Where<SomeType>(x => x.SomeProperty == "123");
The type in <...> after Where is a declaration of generic type parameter. The Where method is generic which means that some of the types involved in its type declaration can be provided when the method is used. In C#, this is called generics.
The <...> is a place where you declare types that the caller needs to specify when using your method. It is, in some way, similar to declarations of parameters
When using parameters, you say that the caller needs to give you some values and you give them names (e.g. source and predicate).
When writing generic method, you say that the caller needs to give you some type and you give the type a name (e.g. TSource) that you can use in the method declaration and body.
A simple answer to your question would be for type safety and IntelliSense while programming. (All the benifits that Generics provide).
LINQ to Objects works on Extension Methods defined in a type named Enumerable. Mostly, they deal with type IEnumerable<T>.
So, for example, when you want it to operate on a List<String>, the Where<TSource> becomes Where<String>. And C# 3.0 type inferance comes into picture so that you dont have to explicitly specify the String part. Since, the compiler knows you are working with IEnumerable<T>.
To sumarrize, when you use Where method on a List, the method expects an IEnumerable<String> and a Predicate that takes String to filter on input sequence as an input and provides with an IEnumerable<String> as an output.

Categories