I'm trying hard to make sense of delegates and lambda expressions and were reading through some of the questions here on stackoverflow and landed on this post where the second example in this comment got me completely lost. The first thing that confuses me is the list parameter not defined anywhere (I understand that it is the input parameter of the return type yet I find difficult to make sense of this code) but I think that everything would be much more clear by seeing how such a definition could be used in practice (and this is the second thing I'm having a hard time grasping).
How could methods such as the following be used in practice?
public Func<IList<T>, T> SelectionMethod<T>()
{
return list => list.First();
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return (x) => { return a * x * x + b * x + c; };
}
The parameters are defined, it's just that their types are inferred. The argument definition is the part before the => - list (inferred to be of type IList<T>) and x (inferred to be of type float) respectivelly in your examples.
The first delegate corresponds to a signature of:
T SomeMethod<T>(IList<T> list)
The second is:
float SomeMethod(float x)
Since the compiler knows what the signature of the delegate must be, it can infer the required types automatically. If you were to write out the delegate using the old-school explicit syntax, it would look something like this:
return (Func<IList<T>, T>)(delegate (IList<T> list) { return list.First(); });
If you really want to use explicit typing, you can specify the types as needed:
(IList<T> list) => list.First()
When you actually want to invoke the delegate, you need to pass the argument, e.g.:
SelectionMethod<string>()(new List<string>())
The first lambda expression is very simple. The second additionally closes over the arguments to the "creator" function, which means that you can access the arguments to the "creator" in the body of the delegate. This is entirely safe in purely immutable code, but may be tricky if you're dealing with mutable reference types and side-effects - make sure you understand the semantics properly before you do anything crazy with those.
Depending on your experience with functional programming, it might be helpful to realize that all of this is just compiler trickery. The two methods will compile to the equivalent of something like this:
public Func<IList<T>, T> SelectionMethod<T>()
{
return new Func<IList<T>, T>(__HiddenAnonymousMethod);
}
private T __HiddenAnonymousMethod<T>(IList<T> list)
{
return list.First();
}
The second example is more complicated because of the closure - we need to create a "helper object" to hold the captured locals:
private class __HiddenAnonymousClass
{
float a, b, c;
public __HiddenAnonymousClass(float a, float b, float c)
{
this.a = a; this.b = b; this.c = c;
}
public float __HiddenAnonymousMethod(float x)
{
return a * x * x + b * x + c;
}
}
public Func<float, float> QuadraticFunctionMaker(float a , float b , float c)
{
return new Func<float, float>
(new __HiddenAnonymousClass(a, b, c).__HiddenAnonymousMethod);
}
Related
I'm trying to make some method like below.
It just add two given objects and return.
object add(object a, object b);
I already tried it with dynamic keyword. Unfortunately this one does not work on iOS. (the platform does not allow runtime code generations)
dynamic add(dynamic a, dynamic b) => a + b;
So, here's my second try and I realized that it's gonna be hell with this way.
private static HybInstance Add(HybInstance a, HybInstance b)
{
if (a.Is<Int32>()) return AddInt32(a, b);
/* and so on... */
}
private static HybInstance AddInt32(HybInstance a, HybInstance b)
{
Int32 ia = a.As<Int32>();
if (b.Is<Int16>()) return HybInstance.Int(ia + b.As<Int32>());
if (b.Is<Int32>()) return HybInstance.Int(ia + b.As<Int32>());
if (b.Is<Int64>()) return HybInstance.Int64(ia + b.As<Int64>());
if (b.Is<float>()) return HybInstance.Float(ia + b.As<float>());
throw new SemanticViolationException($"");
}
// the method should support custom operators too
private static MethodInfo GetAddMethod(HybInstance left) {
return left.GetMethods("op_Addition").FirstOrDefault();
}
Is there any smarter way to add two objects?
addition:
Here are some examples what I want to do.
Just add any kind of objects or throw exception if not possible.
add(1, 1); // 2
add(1, "b"); // exception
add("a", "b"); // "ab"
// and this one also should be work
add(some_class_with_operator_overloading, 10);
Closest you could get using standard .NET types is probably IConvertible:
static IConvertible Add (IConvertible a, IConvertible b)
{
if (a is string) return a.ToString() + b;
if (b is string) return a + b.ToString();
// other special cases here
return a.ToDouble(CultureInfo.CurrentCulture) + b.ToDouble(CultureInfo.CurrentCulture);
}
static void Main(string[] args)
{
IConvertible a = 1;
IConvertible b = 2;
IConvertible s = "string";
Console.WriteLine(Add(a, b));
Console.WriteLine(Add(s, s));
Console.WriteLine(Add(a, s));
}
Produces
3
stringstring
1string
It's impossible to add two objects, because there's nothing about objects that can be added.
It's like you would like add "something" to "something" and expected someone to answer your question with precise answer - it's impossible.
object don't have any fields or properties, so how you'd like to add them??
Unless you have in mind some kind of general rule of adding objects based on their real type, then it would become possible: you would have to check the type of input parameters and then in (rather) huge switch statement return appropriate result (eg. concatenation for strings, simple addition for integers...).
Did you try with generics, 2 things though:
You are wrapping different objects in same wrapper, seems like a design issue, but will leave it since I do not know more.
Most of the int can be directly changed to Int64 and then there will not be that many special cases
I would have a generic function, and would pass it the Add/Combine function which can be defined for different types. Seems to be a cleaner approach.
public T Add<T1, T2, T>(T1 firstObject, T2 secondObject, Func<T1,T2,T>Combine)
{
var result = Combine(firstObject, secondObject);
return result;
}
Update
Seems like this will not work either
Limitations of Xamarin.iOS
No Dynamic Code Generation
Since the iOS kernel prevents an application from generating code dynamically, Xamarin.iOS does not support any form of dynamic code generation. These include:
The System.Reflection.Emit is not available.
No support for System.Runtime.Remoting.
No support for creating types dynamically (no Type.GetType ("MyType`1")), although looking up existing types (Type.GetType ("System.String") for example, works just fine).
Reverse callbacks must be registered with the runtime at compile ti
However
Why does LambdaExpression.Compile() work on iOS (Xamarin)?
On platforms that support code generation, Reflection.Emit-based
LambdaCompiler
is used.
If that's not available, the expression is interpreted using the
interpreter
For example, there are classes that interpret Constant and Add.
Original
I am not sure how much mileage you could get out of this, but you could use expressions
public static object Add<T,T2>(T a,T2 b)
{
var paramA = Expression.Parameter(typeof(T), "a");
var paramB = Expression.Parameter(typeof(T2), "b");
var body = Expression.Add(Expression.Convert(paramA, paramB.Type), paramB);
var add = Expression.Lambda<Func<T, T2, T2>>(body, paramA, paramB).Compile();
return add(a, b);
}
The assumptions it that it will try to convert to the second parameter type and return of that type.
Obviously you any class will need the appropriate operators
Given
public struct Test
{
// user-defined conversion from Fraction to double
public static implicit operator int(Test f)
{
return 10;
}
public static implicit operator Test(int i)
{
return new Test();
}
// overload operator *
public static Test operator +(Test a, Test b)
{
return new Test();
}
}
Example
Console.WriteLine(Add(1, 2));
Console.WriteLine(Add(1, 2.0));
Console.WriteLine(Add(1, new Test()));
Refelction can be used to walk the properties of both objects, check for name equivalency and numeric data type, then amend property values in a totally generic way:
public static void AddObjects(object oFrom, object oTo)
{
if (oFrom != null && oTo != null)
{
foreach (System.Reflection.PropertyInfo f in oFrom.GetType().GetProperties())
{
if ((oTo).GetType().GetProperty(f.Name) != null)
{
try
{
string sType = f.GetType().ToString().ToLower();
if (sType==("int") )
{
oFrom.GetType().GetProperty(f.Name).SetValue(oFrom, (int)(f.GetValue(oFrom)) + (int)(f.GetValue(oTo)));
}
if (sType=="int32" )
{
oFrom.GetType().GetProperty(f.Name).SetValue(oFrom, (Int32)(f.GetValue(oFrom)) + (Int32)(f.GetValue(oTo)));
}
if (sType==("int64") )
{
oFrom.GetType().GetProperty(f.Name).SetValue(oFrom, (Int64)(f.GetValue(oFrom)) + (Int64)(f.GetValue(oTo)));
}
// keep adding for all numeirc types. maybe theres a better way?
}
catch (Exception ex)
{ }
}
}
}
}
Im trying to create a ufloat class/struct in c#. It's more of a challenge for me, but would help me control some values in code. After trying a couple of approaches, I finally have one that seems to work:
public struct ufloat
{
public float Value
{
get{ return value; }
set
{
if(value < 0)
{
this.value = 0;
}
else
{
this.value = Math.Abs(value);
}
}
}
}
The problem is, I want it to behave like a typical basic type:
ufloat n = 5;
n += 1;
After some thinking I tried to overload the '=' operator, but it is not possible. Now I am out of ideas. This is why I ask, how can you change this:
ufloat x; x.value = 1;
to this:
ufloat x = 0; x = 1;
?
(Sorry if I am losing something really easy, but I am a self-taught "programmer" and I am pretty new to c#. I learnt c++ at first, and going from lower to higher level isn't easy for me.)
You can't overload the = operator, but you can overload the + operator, and then the += operator (which I believe you meant instead of =+) will work in a reasonably obvious way. You'd also need to add an implicit conversion from float to your struct though.
I would strongly advise not making the struct mutable though - instead, let the + operator return a new value. That will make it behave like every other primitive type, and like most other structs. I'd also rename it to USingle to follow the normal .NET naming conventions (where Single is the CLR name for float). You can't add your own C# alias for a name like float is for Single though.
I suspect your type will want:
A constructor accepting a float
Conversions to and from float (note that normally implicit conversions shouldn't throw exceptions - you may want to ignore that, but I'm not sure...)
Overloads for the arithmetic operators (+, -, * and /)
Overrides of ToString, Equals and GetHashCode
Implementation of IComparable<USingle> and IEquatable<USingle>
You should think about what you want to happen if you add two values which are "large positive floats" together - is the intention that your new type is able to support larger positive values than float can, or is it just "float but always non-negative"?
You can not overload = operator but you may write implicit casts, for example this one is for casting an int:
public class ufloat
{
public float value { get; }
public ufloat(int val) { value = Math.Abs(val); }
public static implicit operator ufloat(int input)
{
return new ufloat(input);
}
}
Now if you assign an int value to it, it will implicitly be converted to ufloat:
ufloat x = -5;
I would like to create a generic method which performs basic mathematical operations. For eg. If a double is passed to the function, it will return double.
public static T Multiply<T> (T A, int B)
{
//some calculation here
return (T) A * B;
}
This doesn't work for me.
EDIT: I get an error Operator '*' cannot be applied to operands of type 'T' and 'int'
However I am wondering if there are other ways to achieve what I am trying to?
Thanks
You can do it by constructing and compiling a LINQ expression for the specific type, like this:
private static IDictionary<Type,object> MultByType = new Dictionary<Type,object>();
public static T Multiply<T>(T a, int b) {
Func<T,int,T> mult;
object tmp;
if (!MultByType.TryGetValue(typeof (T), out tmp)) {
var lhs = Expression.Parameter(typeof(T));
var rhs = Expression.Parameter(typeof(int));
mult = (Func<T,int,T>) Expression.Lambda(
Expression.Multiply(lhs, Expression.Convert(rhs, typeof(T)))
, lhs
, rhs
).Compile();
MultByType.Add(typeof(T), mult);
} else {
mult = (Func<T,int,T>)tmp;
}
return mult(a, b);
}
To avoid recompiling the expression each time it is used, one could cache it in a dictionary.
Note that this approach has certain limitations:
Multiplication of T by T is expected to be defined,
The output of multiplication is expected to be T without conversion. This is not true for types smaller than int,
The type must support conversion from int.
None of this is checked at compile time.
This is the simplest to implement, but is not efficient:
public static T Multiply<T>(T A, int B)
{
T val = default(T);
try
{
val = (dynamic)A * B;
}
catch
{ }
return val;
}
Depending on your needs it might be fine for you. You may consider not handling the exception in the method, or using an out value so that you can return both the answer and a success value.
Being stuck on an on older .Net version, without access to dynamic, I have a very simple class that does very much what you're looking for, and allows for use of actual operators: Numeric It may be worth a look on current .Net as well.
Method declaration:
public static T LerpMinMax<T>(Numeric<T> input, Numeric<T> inputMin, Numeric<T> inputMax, Numeric<T> outputMin, Numeric<T> outputMax)
{
if (input <= inputMin)
{
return outputMin;
}
else if (input >= inputMax)
{
return outputMax;
}
return outputMin + ((input - inputMin) / (inputMax - inputMin)) * (outputMax - outputMin);
}
And then use:
float lerp = LerpMinMax<float>(0.55f, 0.0f, 0.1f, 0.0f, 1000.0f);
It's definitely not as flexible as MiscUtil's Operator, but was intended to be simple and (relatively) fast. It's still significantly slower than using operations directly (say by using T4 templates that spit out non-generic type-specific implementations) but used in the above way it's equivalent to MiscUtil's Operator class. It also obviously has the benefit of generally more readable algorithm implementations, and can support custom classes that implement operators.
You should add Dynamic in front of the A
and the conversion to T must be done on the full calculation
public static T Multiply<T>(T A, int B)
{
return (T)((dynamic)A * B);
}
Here's my example for using generics to compare to numbers:
public bool TIsEqual<T>(T f1, T f2, T margin)
{
T diff = default(T);
T error = default(T);
diff = Math.Abs((dynamic)f1 - f2);
error = (dynamic)margin * f1;
return (dynamic) diff < error;
}
Below a Compose function. If f and g are unary functions which return values, then Compose(f,g) returns a function which when called on x performs the equivalent to f(g(x)).
static Func<X, Z> Compose<Z, Y, X>(Func<Y, Z> f,Func<X, Y> g)
{ return x => f(g(x)); }
Here's a couple of simple Func values which can be composed:
Func<int, bool> is_zero = x => { return x == 0; };
Func<int, int> mod_by_2 = x => { return x % 2; };
E.g. this works:
Console.WriteLine(Compose(is_zero, mod_by_2)(4));
However, if I instead have these equivalent static methods:
static bool IsZero(int n) { return n == 0; }
static int ModBy2(int n) { return n % 2; }
the same example doesn't work with those. I.e. this produces a compile time error:
Console.WriteLine(Compose(IsZero, ModBy2)(4));
Explicitly passing types to Compose fixes the issue:
Console.WriteLine(Compose<bool, int, int>(IsZero, ModBy2)(4));
Is there anyway to write Compose such that it works on the static methods without the explicit types?
Is this a good approach to take to implementing Compose? Can anyone make improvements to this?
The problem here is not the use of static methods but the use of method groups. When you use a function name as an expression without invoking it then it's a method group and must go through method group conversion. You would have the exact same problem with instance methods.
The problem you're running into is that C# can't do return type inference on method groups. Using Compose(IsZero, ModBy2)) requires the return type to be inferred for both IsZero and ModBy2 and hence this operation fails.
This is a known limitation in the inference capabilities of the C# compiler. Eric Lippert wrote an extensive blog article on this particular subject which covers this problem in detail
http://blogs.msdn.com/b/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Function overloading by return type?
Hi,
In overloading we say that the parameter list has to be different either by number or by type, but doesn't matter on the return type, Why is that so???
The function
//Function 1
int Add(int a, int b)
{return a+b;}
//Function 2
Double Add(Double a, Double b)
{return a+b;}
//Function 3
Double Add(int a, int b)
{return (Double)a+b;}
The functions 1 2 are overloaded, where as functions 1 and 3 are not ??? Reasons ???
Any help is really appreciated.
The compiler needs to know at compile time which function you are trying to call. If they differ only by return type, this is usually not possible. Consider, for example:
var result = Add(1, 2);
or
Console.WriteLine(Add(1, 2));
the compiler would not be able to know whether you want to execute function 1 or 3. And even if you did
double x = Add(1, 2);
the compiler would not know if you (a) want to call function 3 or (b) call function 1 and do an implicit widening conversion from int to double.
There are to many cases where that kind of overloading would not work. Here is two of them:
You don't care about the result of the method, and call it like this:
Add(3, 4);
Should this call method 1 or 3?
You use varto assign the result
var result = Add(3, 4);
This kind of overloading would be ambiguous at best, so therefore it's not allowed.
The other answers deal with why, but an aside: in C# you can simulate return-type based overloading by using (abusing?) implicit conversion operators (and deferring the operation):
using System;
class Program {
static void Main() {
int i = Add(3, 5); // prints: int overload called
double d = Add(3, 5); // prints: double overload called
}
static SuperMagicAdder Add(int a, int b)
{ return new SuperMagicAdder(a, b); }
}
struct SuperMagicAdder {
private readonly int a,b;
public SuperMagicAdder(int a, int b) { this.a = a; this.b = b; }
public override string ToString() { return a + "+" + b; }
public static implicit operator int (SuperMagicAdder value) {
Console.WriteLine("int overload called");
return value.a + value.b;
}
public static implicit operator double (SuperMagicAdder value) {
Console.WriteLine("double overload called");
return (double)value.a + value.b;
}
}
Note that interestingly, Anonymous Function Literals in C# are overloaded on their result type and it doesn't seem to pose any problems.
In C#, a lambda can be two very different things:
a piece of executable code (a subclass of Delegate actually)
an abstract representation of an operation (basically, an abstract syntax tree)
This is distinguished purely by the result type of the lambda literal:
Func<int, int> l = (i) => i + i * i;
is a piece of executable code. I can say
Console.WriteLine(l(3));
and I will get 12.
Expression<Func<int, int>> e = (i) => i + i * i;
is an abstract representation of that operation. I can say
Console.WriteLine(e);
and I will get
i => (i + (i * i))
Note that this is not just the original text. It really is an rendering of the abstract representation. The extra parentheses around the expression and inside it are there, because ToString() did an actual tree traversal of the AST and rendered it. The AST looks roughly like this:
And this
var v = (i) => i + i * i;
is simply illegal, because lambdas are overloaded on their result type, but the var keyword says "use the result type to figure out the type of v".
Allowing return types to be part of the signature would create major ambiguities in overload resolution.
For example, consider:
Add(2,3);
We are "throwing away" the value returned by the method, but which overload should be invoked?
It doesn't work well with implicit-typing, or with assigning the value to a variable that is compatible with either return-type. E.g.:
var sum = Add(2,3);
object sum = Add(2,3);