I have two objects that can be represented as an int, float, bool, or string. I need to perform an addition on these two objects with the results being the same thing c# would produce as a result. For instance 1+"Foo" would equal the string "1Foo", 2+2.5 would equal the float 5.5, and 3+3 would equal the int 6 . Currently I am using the code below but it seems like incredible overkill. Can anyone simplify or point me to some way to do this efficiently?
private object Combine(object o, object o1) {
float left = 0;
float right = 0;
bool isInt = false;
string l = null;
string r = null;
if (o is int) {
left = (int)o;
isInt = true;
}
else if (o is float) {
left = (float)o;
}
开发者_开发技巧 else if (o is bool) {
l = o.ToString();
}
else {
l = (string)o;
}
if (o1 is int) {
right = (int)o1;
}
else if (o is float) {
right = (float)o1;
isInt = false;
}
else if (o1 is bool) {
r = o1.ToString();
isInt = false;
}
else {
r = (string)o1;
isInt = false;
}
object rr;
if (l == null) {
if (r == null) {
rr = left + right;
}
else {
rr = left + r;
}
}
else {
if (r == null) {
rr = l + right;
}
else {
rr = l + r;
}
}
if (isInt) {
return Convert.ToInt32(rr);
}
return rr;
}
Can you use .NET 4.0? If so, it becomes very simple using dynamic typing:
private object Combine(dynamic o, dynamic o1)
{
// Assumes an appropriate addition operator, found at execution time
return o + o1;
}
Another alternative is to have a map of delegates for each pair of possible types. It's unfortunate that before .NET 4.0 there's no Tuple
type, so you'll have to define your own TypePair
type as the map key. Of course you then need to make sure you cover every possible pair... but at least the compiler can help when you've got a suitable "AddDelegate" method:
private void AddDelegate<T1, T2>(Func<T1, T2, object> sumFunction)
{
// Put the function in the map
...
}
AddDelegate<int,int>((x, y) => x + y);
AddDelegate<int,float>((x, y) => x + y);
AddDelegate<int,string>((x, y) => x + y);
AddDelegate<float,int>((x, y) => x + y);
AddDelegate<float,float>((x, y) => x + y);
AddDelegate<float,string>((x, y) => x + y);
...
Btw, I've taken bool
out of that as "addition" between a bool
and a float
(for example) doesn't make any sense. You can decide how you'd want to combine them though.
As Mitch says though, I'd revisit your design decisions - are you sure you really need this? It's a pretty odd requirement. Can you tell us anything about the bigger picture? We may be able to suggest alternative approaches.
You could just overload the method with the different types you want to use. It’s type-safe and simple.
private string Combine(string o1, string o2) { return o1 + o2; }
private string Combine(string o1, int o2) { return o1 + o2; }
private string Combine(string o1, float o2) { return o1 + o2; }
private string Combine(float o1, string o2) { return o1 + o2; }
private float Combine(float o1, int o2) { return o1 + o2; }
private float Combine(float o1, float o2) { return o1 + o2; }
private string Combine(int o1, string o2) { return o1 + o2; }
private float Combine(int o1, float o2) { return o1 + o2; }
private int Combine(int o1, int o2) { return o1 + o2; }
精彩评论