Reputation: 73112
Don't know if this has been asked before, so point me to another question if it has.
I've got a method like this:
private void SomeMethod<TLocation>(int x, int y) where TLocation : DataLocation
{
//
}
In the method i wish to call it with, i have an enum, and i want to call the method with the type parameter.
public enum LocationType
{
Country,
State,
County,
City,
Neighborhood,
Street
}
Types of DataLocation:
DataCountry
DataState
DataCounty
DataCity
DataNeighborhood
DataStreet
Knowing that the type parameter is "Data" + enum name, is there any way i can dynamically call my method?
Or should i stick with:
switch (locationType)
{
case LocationType.Country:
SomeMethod<DataCountry>(1, 2);
break;
case LocationType.State:
SomeMethod<DataState>(2, 4);
break;
// etc
}
EDIT:
Looks like reflection is the only way. I'll be sticking with the switch.
Upvotes: 1
Views: 341
Reputation: 51319
It sounds like this method should be defined as a member of the DataState class, and overridden accordingly, possibly with internal use of this.GetType()
. You are kind of abusing generics here.
That said... (I almost hope I am downvoted for this...)
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new ResolveIt<LocationType>().InvokeIt(LocationType.State, 1, 5);
Console.ReadLine();
}
}
public class ResolveIt<TEnum> // Unfortunately can't constrain on enums
{
private static readonly Action<int, int>[] Actions
= Enum.GetValues(typeof(TEnum))
.Cast<TEnum>()
.Select(v => typeof(ResolveIt<TEnum>)
.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
.First(n => n.Name == "SomeMethod")
.GetGenericMethodDefinition()
.MakeGenericMethod(new[] { Type.GetType(typeof(ResolveIt<TEnum>).Namespace + ".Data" + Enum.GetName(typeof(TEnum), v)) }))
.Select(mi => (Action<int, int>)Delegate.CreateDelegate(typeof(Action<int, int>), mi))
.ToArray();
public void InvokeIt(TEnum type, int x, int y)
{
Actions[(Int32)Convert.ChangeType(type, typeof(Int32))](x, y);
}
private static void SomeMethod<TLocation>(int x, int y) where TLocation : DataLocation
{
Console.Out.WriteLine(typeof(TLocation));
}
}
public enum LocationType { Country, State, City, Zip, }
public class DataLocation { }
public class DataCountry:DataLocation { }
public class DataState:DataLocation { }
public class DataCity:DataLocation { }
public class DataZip:DataLocation { }
}
Upvotes: 0
Reputation: 17850
Here is the possible solution:
var dispatches = new Dictionary<LocationType, Action<int, int>>();
dispatches.Add(LocationType.Country, SomeMethod<DataCountry>);
dispatches.Add(LocationType.State, SomeMethod<DataState>);
//... and etc.
dispatches[LocationType.Country](1, 2); // the same as SomeMethod<DataCountry>(1,2)
Upvotes: 1
Reputation: 6612
You can always refactor your switch case and put case specific code in separate functions. Here is nice article about it- http://elegantcode.com/2009/01/10/refactoring-a-switch-statement/
Upvotes: 0
Reputation: 1863
I think you should stick with the implementation you suggested using the switch statement. It is clear and concise plus I am unaware of how you could do it dynamically.
Upvotes: 0