2016-01-25 1 views
0

У меня есть метод в C#, который принимает общий тип в качестве аргумента:условный код на основе общего параметра типа с C#

private void DoSomething<T>(T param) 
{ 
    //... 
} 

мне нужно выполнять различные действия в зависимости от того, какой является param из. Я знаю, что могу достичь его с несколькими if предложениями, например:

private void DoSomething<T>(T param) 
{ 
    if (param is TypeA) 
    { 
     // do something specific to TypeA case 

    } else if (param is TypeB) 
    { 
     // do something specific to TypeB case 

    } else if (...) 
    { 
     ... 
    } 

    // ... more code to run no matter the type of param 
} 

Есть ли лучший способ сделать это? Может быть, с switch-case или другим подходом, о котором я не знаю?

+8

В общем, если вы делаете что-то по своей сути специфично для типов, общий метод является неправильным инструментом. Возможно, создайте метод с перегрузками типа, который вызывает общий метод после его завершения? –

+0

Можете ли вы объяснить, что вы пытаетесь сделать? –

+3

это может привести к хорошему чтению [Ограничения по типам парамов] (https://msdn.microsoft.com/en-us/library/d5x73970.aspx) – MethodMan

ответ

2

Вы можете создать конкретный метод для определенного типа.

private void DoSomething<T>(T param) 
    { 
     //... 
    } 

    private void DoSomething(int param) { /* ... */ } 

    private void DoSomething(string param) { /* ... */ } 
3

Если структура проекта/логики позволяет легко перемещать DoSomething в T и описывать его с интерфейсом IDoSomething. Таким образом, вы можете написать:

private void DoSomething<T>(T param) where T:IDoSomething 
{ 
    param.DoSomething() 
} 

Если это не вариант, то вы можете настроить словарь правил

var actionsByType = new Dictionary<Type, Action<T /*if you neeed that param*/>(){ 
    { Type1, DoSomething1 }, 
    { Type2, DoSomething2 }, 
    /.. 
} 

и в вашем методе вы можете позвонить:

private void DoSomething<T>(T param){ 
    //some checks if needed 
    actionsByType[typeof(T)](param/*if param needed*/); 
} 
+0

Я собирался пойти со своей первой идеей, довольно хорошо! Но моя структура проекта этого не позволяла. Второй тоже хорош, но сначала попробую с простой перегрузкой. Благодаря! – zed

5

Просто используйте перегрузки вместо дженериков.

1

Как упоминалось ранее, если в его простом случае используется перегрузка. Любой незнакомец вы можете адаптировать это (его быстрые и грязные извинения).

class Program 
{ 

    interface IDoSomething<T> 
    { 
     void DoSomething(T param); 
    } 

    class Test : IDoSomething<int>, IDoSomething<string> 
    { 
     public void DoSomething(int param) 
     { 

     } 

     public void DoSomething(string param) 
     { 

     } 
    } 

    static void Main(string[] args) 
    { 

     DoSomething(4); 

    } 

    static void DoSomething<T>(T param) 
    { 
     var test = new Test(); 
     var cast = test as IDoSomething<T>; 
     if (cast == null) throw new Exception("Unhandled type"); 
     cast.DoSomething(param); 
    } 
} 
Смежные вопросы