Clever way to add two objects - c#

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)
{ }
}
}
}
}

Related

Why do I have to type-cast a strongly typed function using a dynamic input-parameter?

I have a converter method:
MyPoco Convert(dynamic p) => new MyPoco { A = p.X, B = p.Y };
void Test()
{
dynamic item = new { X = 1, Y = 2 };
var poco = (MyPoco)Convert(item);
}
I have to explictly cast the result to MyPoco, otherwise poco will become a dynamic variable, too.
But, if I inline the Convert method;
void Test()
{
MyPoco Convert(dynamic p) => new MyPoco { A = p.X, B = p.Y };
dynamic item = new { X = 1, Y = 2 };
var poco = Convert(item);
}
I don't need to cast ConvertItem to MyPoco. Is there a reason for this behavior? It should be easy for the compiler to know that Convert return-type is MyPoco, right?
There is a difference between them which could be the reason - local functions don't support overloading. I think it is important - imagine we have two methods with the same name and with different input and output types
static void Main(string[] args)
{
dynamic d = null;
var result = Hello(d);
Console.WriteLine("Hello World!");
}
static string Hello(string s)
{
return s;
}
static int Hello(int i)
{
return i;
}
It means the result may be string or int - we don't know it in compile time.
While for the following code we get the error that local variable or function already declared
static void Main(string[] args)
{
string Hello(string s)
{
return s;
}
int Hello(int s) // error - local variable or function with the same name already declared
{
return s;
}
dynamic d = null;
var result = Hello(d);
Console.WriteLine("Hello World!");
}
We can only write something like this
static void Main(string[] args)
{
string Hello(string s)
{
return s;
}
dynamic d = null;
var result = Hello(d);
Console.WriteLine("Hello World!");
}
So when compiler sees the local Hello(...) call it knows that return type is string.
Upd:
Regarding the compiler ability to infer correct type in case of dynamic.
I think yes, it is possible for compiler to catch such cases - if we know in compile time that there is the only one method,
there is no chance that in runtime another one will appear.
I could imagine e.g. the method we call is in another assembly, and in runtime we loaded newer version which has different signature - with dynamic it will work, but for the, say, private static method with no overloads I think we could infer non-dynamic type.
But I think, it is was decided to implement it that way for the sake of simplicity - it is easier to keep in mind simple rule - everything that touches dynamic - dynamic.
For local functions for simplicity I think it would be easier to also have them dynamic. I think it is just decision made by different people implementing that.
I checked the roslyn source code trying to find information about that.
The place where it is defined is Binder_Invocation.cs, BindMethodGroupInvocation method.
For local function the following method is called
private BoundExpression BindLocalFunctionInvocationWithDynamicArgument(
SyntaxNode syntax,
SyntaxNode expression,
string methodName,
BoundMethodGroup boundMethodGroup,
DiagnosticBag diagnostics,
CSharpSyntaxNode queryClause,
MethodGroupResolution resolution)
{
// Invocations of local functions with dynamic arguments don't need
// to be dispatched as dynamic invocations since they cannot be
// overloaded. Instead, we'll just emit a standard call with
// dynamic implicit conversions for any dynamic arguments. There
// are two exceptions: "params", and unconstructed generics. While
// implementing those cases with dynamic invocations is possible,
// we have decided the implementation complexity is not worth it.
// Refer to the comments below for the exact semantics.
As you can see the also say about overloading, but for the normal method call no any information about the reason
else
{
if (HasApplicableConditionalMethod(resolution.OverloadResolutionResult))
{
// warning CS1974: The dynamically dispatched call to method 'Goo' may fail at runtime
// because one or more applicable overloads are conditional methods
Error(diagnostics, ErrorCode.WRN_DynamicDispatchToConditionalMethod, syntax, methodGroup.Name);
}
// Note that the runtime binder may consider candidates that haven't passed compile-time final validation
// and an ambiguity error may be reported. Also additional checks are performed in runtime final validation
// that are not performed at compile-time.
// Only if the set of final applicable candidates is empty we know for sure the call will fail at runtime.
var finalApplicableCandidates = GetCandidatesPassingFinalValidation(syntax, resolution.OverloadResolutionResult,
methodGroup.ReceiverOpt,
methodGroup.TypeArgumentsOpt,
diagnostics);
if (finalApplicableCandidates.Length > 0)
{
result = BindDynamicInvocation(syntax, methodGroup, resolution.AnalyzedArguments, finalApplicableCandidates, diagnostics, queryClause);
}
else
{
result = CreateBadCall(syntax, methodGroup, methodGroup.ResultKind, analyzedArguments);
}
They create dynamic if there is at least one canditate.
So, as I said, I think it could be done non-dynamic, but the people who implemented it originally kept it dynamic, probably for simplicity.
What you could do in order to find more details is to try to implement the case when no overloading methods, changing the code
if (finalApplicableCandidates.Length > 0)
{
result = BindDynamicInvocation(syntax, methodGroup, resolution.AnalyzedArguments, finalApplicableCandidates, diagnostics, queryClause);
}
by adding the check if Length == 1 then call BindInvocationExpressionContinued instead of BindDynamicInvocation
and run the tests and check if something fails, maybe it helps.(I didn't even manage to get the roslyn project built, dotnet core is a bit weird)
P.S.
According to this
if (boundMethodGroup.TypeArgumentsOpt.IsDefaultOrEmpty && localFunction.IsGenericMethod)
{
Error(diagnostics, ErrorCode.ERR_DynamicLocalFunctionTypeParameter, syntax, localFunction.Name);
return BindDynamicInvocation(
For local function we could get dynamic instead of concrete type.
If you type something like this
static void Main(string[] args)
{
int TestFunc<T>(T data)
{
return 1;
}
dynamic d = 2;
var r = TestFunc(d);
}
Yes, it will give the error, but if you check the inferred type it of r will show dynamic))

c# generic method for mathematical operations

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;
}

Create a variable of a type only known at runtime (C#)

My question is very similar to : Cast to type known only at runtime , however that one was not really answered (it's also in C rather than C#).
I'm writing something to control some hardware, and depending on the given hardware configuration I have to do some bitwise arithmetic with a "byte" or "UInt32" type. The bit arithmetic code is long but identical in the 32bit and 8bit case, with the only difference being the length of certain loops (32 or 8).
My current solution is to use a switch, which means I have pretty much two copies of the same code in a giant if statement.
An alternative solution is to use an array or 0s and 1s rather than a UInt32 or byte to do the bitwise operations and then convert to UInt32 or byte at the end.
The last solution, which I'm most interested in here, is to dynamically pick which type I will use at runtime. Here is some pseudocode for what I would like:
System.Type MyType;
if (something)
MyType=type1;
else
MyType=somethingElse;
myType someVariable; //Create a variable of type myType. This line will give an
//error
someVariable=(myType) otherVariable //do an example typecast with the
//runtime-determined type
I've searched around to know that the answer may have something to do with generics and reflection, but I can't figure out how to do it exactly.
You might consider using a BitArray for this - you can initialise it from a byte or uint32, do the bitwise operations, and then convert it back at the end e.g.
object value;
bool isByte = value is byte;
BitArray ba = isByte
? new BitArray(new byte[] { (byte)value })
: new BitArray(BitConverter.GetBytes((unint32)value));
...
I would probably create an abstract class, something like HardwareConfigBase which includes your looping code as well as the size of the loop. Then have 2 child classes that extend that base class.
public abstract class HardwareConfigBase
{
protected int TimesToLoop;
public byte[] Data = new byte[32 * 8]; //Size of UInt, but still works for 8bit byte
public void MyLoopCode
{
for(int i = 0; i < TimesToLoop; i++)
{
//Do whatever
}
}
}
public class ByteHardwareConfig
{
public ByteHardwareConfig
{
TimesToLoop = 8;
}
}
public class UIntHardwareConfig
{
public UIntHardwareConfig
{
TimesToLoop = 32;
}
}
public void Main()
{
var myHardwareConfig = new ByteHardwareConfig(); //Could also be UInt
//Do some more initialization and fill the Data property.
myHardwareConfig.MyLoopCode();
}
You can create an instance of a type at runtime using Activator.CreateInstance() like so:
object myInstance = Activator.CreateInstance(MyType);
Then, see this question for how to do a type cast at runtime using only runtime-known types.
public static dynamic Convert(dynamic source, Type dest) {
return Convert.ChangeType(source, dest);
}
myInstance = Convert(myInstance, MyType);
// will result in myInstance being of type MyType.
The answer is rather pretty simple. You will not need to cast or convert any variables at runtime in order to be able to modify uint or byte types at runtime. The following three definitions will suffice.
The first class definition is the Provider class which defines two methods, each one to modify either a variable of uint or byte type. Be sure to put your modifying logic inside the methods.
class Provider
{
public uint GetResult(uint c)
{
return c;
}
public byte GetResult(byte c)
{
return c;
}
}
The next class is the one that will invoke the appropriate method from the previous class definition, depending on the type of the parameter you provide.
class Execute
{
public object GetResult(object source)
{
var provider = new Provider();
return provider.GetType()
.GetMethods()
.Where(x => x.Name == "GetResult" && x.ReturnType == source.GetType())
.First()
.Invoke(provider, new object[] { source });
}
}
The last definition is here to simply test how this setup works. You can see that we have both a byte and a uint type. Passing them both to the GetResult(object) method yields the expected results, and as you can see, the underlying system type is also as expected.
class Program
{
static void Main()
{
uint u = 1;
byte b = 2;
var result1 = new Execute().GetResult(u);
var result2 = new Execute().GetResult(b);
sc.WriteLine(result1 + " " + result1.GetType().UnderlyingSystemType);
sc.WriteLine(result2 + " " + result2.GetType().UnderlyingSystemType);
sc.Read();
}
}
Try using the dynamic keyword in C#.
dynamic myType;
if (a) {
myType = new type1();
} else {
myType = new type2();
}

Why does string concatenation with the + operator work with dynamic types in C#?

I recently saw an example where the following was demonstrated to work:
T Add<T>(dynamic a, dynamic b)
{
return a + b;
}
Add<string>("hello", "world"); // Returns "helloworld"
However, if I were to attempt to use expressions to create a "generic" Add function:
ParameterExpression left = Expression.Parameter(typeof(T), "left");
ParameterExpression right = Expression.Parameter(typeof(T), "right");
var add = Expression.Lambda<Func<T, T, T>>(Expression.Add(left, right), left, right).Compile(); // Fails with System.InvalidOperationException : The binary operator Add is not defined for the types 'System.String' and 'System.String' when T == String.
and then used this function with strings, it fails because the String type does not actually implement the + operator, but is simply syntactic sugar for String.Concat().
How then, does dynamic allow this to work? I figured that at runtime it is past the point where + would be rewritten using String.Concat().
dynamic uses runtime helper functions that replicate C# compiler rules. One of these rules allows + on string objects even when no operator is defined by the framework. The standard numeric types such as int have no custom operator overload either, that too is done by the compiler and needs to be performed at runtime when using dynamic. This is why you need a reference to Microsoft.CSharp.dll: dynamic cannot work without those helper functions.
Based on the documentation, maybe instead of Expression.Add(left, right) you could say Expression.Add(left, right, method) where method is the MethodInfo of the static String.Concat(String, String).
var method = typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string), });
EDIT: Hmm, my answer sort of misses the point. The interesting question is: What operations does the runtime consider when it tries to resolve a + that the compiler has let through without type-checking? Bulit-in addition for numeric types? String concatenation? Delegate concatenation? User-defined operator overloads?
In your first example a and be are still strings (try this):
// Define other methods and classes here
T Add<T>(dynamic a, dynamic b)
{
Console.WriteLine(a.GetType());
Console.WriteLine(b.GetType());
return a + b;
}
Maybe this makes more sense?
void Main()
{
var x = Add<string>(new { val = "hello"},new { val = "world"}); // Returns "hello world"
Console.WriteLine(x);
}
// Define other methods and classes here
T Add<T>(dynamic a, dynamic b)
{
return a.val + b.val;
}

In overloading why the return type of the function is not considered? [duplicate]

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);

Categories

Resources