Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write a generic method to replace a family of legacy API methods

Tags:

c#

generics

I'm writing code using a legacy API whose code I cannot change. There is a family of methods for supported datatypes (int, double, bool, string, APIObject) to do an operation in the API. These take a parameter of the same datatype as indicated in the name of the method. Sample usages as given below

GetIntExp(5)
GetStringExp("Hello")
GetDoubleExp(1.2)
GetDateExp(DateTime.Now)
GetAPIObjectExp(myObject)

The return type respectively, IntExp, StringExp, DoubleExp, DateExp and ObjectExp. All return types inherit from a class (which interestingly is a generic type) StaticOperator<T> where T is the datatype.

Is it possible to write a generic method in my codebase which redirects calls to the suitable API method based on the datatype which is passed in?

like image 961
Rahul Misra Avatar asked Jun 30 '14 08:06

Rahul Misra


People also ask

Why use generic methods?

In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.

How do you create a generic method in C#?

You can create an instance of generic classes by specifying an actual type in angle brackets. The following creates an instance of the generic class DataStore . DataStore<string> store = new DataStore<string>(); Above, we specified the string type in the angle brackets while creating an instance.

Can return type be generic in Java?

(Yes, this is legal code; see Java Generics: Generic type defined as return type only.) The return type will be inferred from the caller.

How does a generic method differ from a generic type?

From the point of view of reflection, the difference between a generic type and an ordinary type is that a generic type has associated with it a set of type parameters (if it is a generic type definition) or type arguments (if it is a constructed type). A generic method differs from an ordinary method in the same way.


2 Answers

Seems to me you don't need a generic method at all, just a wrapper method for each supported argument type:

public IntExp GetExpression(int value)
{
    return GetIntExp(value);
}

public StringExp GetExpression(string value)
{
    return GetStringExp(value);
}

and so on (assuming your goal is to use the same name for all the ways of getting an expression).

like image 194
Matthew Watson Avatar answered Nov 15 '22 02:11

Matthew Watson


Something like

private Dictionary<Type, Func<object, object>> _funcMapping = new Dictionary<Type, Func<object, object>> {
    {typeof(Int), (input) => GetIntExp((int)input)},
    {typeof(string), (input) => GetStringExp((string)input)},
    ...
};

public StaticOperator<TType> GetExp<TType>(TType target) {
    Func<object, object> func;
    if (!_funcMapping.TryGetValue(typeof(TType), out func))
        throw new NotImplementedException();
    return (StaticOperator<TType>)func(target);
} 

is totally possible, but certainly have scaling problems and quite unsafe as requires a lot of casting.

Of course you can rewrite it using if .. elseif .. elseif .. elseif .. else, but all in all it's just a checking if we have a suitable method.

like image 29
J0HN Avatar answered Nov 15 '22 03:11

J0HN