2016-11-16 3 views
-3

Использование ключевого слова dynamic работает в этом методе, как показано здесь, но я пытаюсь выяснить способ сделать это, не используя dynamic или var. Я бы хотел использовать общий подход. Есть ли какие-либо шаблоны или утилиты преобразования, которые я мог бы использовать?Преобразование из общего типа в другой тип в общий метод

public static TAngle AngleBetween<TAngle>(Vector vector1, Vector vector2) where TAngle : IAngle 
{ 
    dynamic radians = (Radian)AngleBetween(vector1, vector2); 

    return (TAngle)radians; 
} 

Это дает желаемый результат, но это нарушает принцип Лиск:

public static TAngle AngleBetween<TAngle>(Vector vector1, Vector vector2) where TAngle : IAngle 
    { 
     double result = AngleBetween(vector1, vector2); 

     Radian    resultRadian = new Radian(result); 

    Degree    testDegree = new Degree(); 
     DegreeMinuteSecond testDMS  = new DegreeMinuteSecond(); 
     Gradian    testGradian = new Gradian(); 
     Turn    testTurn  = new Turn(); 

     if (typeof(TAngle) == typeof(Degree)) 
     { 
      testDegree = (Degree)resultRadian; 
      return (TAngle)(object)testDegree; 
     } 
     else if (typeof(TAngle) == typeof(DegreeMinuteSecond)) 
     { 
      testDMS = (DegreeMinuteSecond)resultRadian; 
      return (TAngle)(object)testDMS; 
     } 

     else if (typeof(TAngle) == typeof(Gradian)) 
     { 
      testGradian = (Gradian)resultRadian; 
      return (TAngle)(object)testGradian; 
     } 

     else if (typeof(TAngle) == typeof(Turn)) 
     { 
      testTurn = (Turn)resultRadian; 
      return (TAngle)(object)testTurn; 
     } 

     else return (TAngle)(object)resultRadian; 

    } 

Кто-нибудь есть какие-либо предложения?

+3

Думаю, нам нужна реализация 'Radian' и' IAngle' здесь, чтобы ответить на этот вопрос. – Jamiec

+2

Я сомневаюсь, что компилятор может гарантировать, что 'TAngle' всегда будет« Radian ». Если метод может * только * когда-либо использовать «Радиан», то зачем делать его общим? Просто верните «Радиану». – David

+0

Имеет ли 'TAngle' какие-либо ограничения? – dymanoid

ответ

4

компилятор не может гарантировать, что это всегда будет успешным:

TAngle radians = (Radian)AngleBetween(vector1, vector2); 

В конце концов, что, если TAngle является чем-то кромеRadian? Ограничение на нем:

where TAngle : IAngle 

Но нет времени компиляции гарантирует, что Radian это единственное, что будет когда-либо реализовать IAngle.

Отсюда ошибка.

Но, к тому же, учитывая реализацию этого метода, он не должен быть общим в первую очередь. Поскольку вы всегда хотите вернуть Radian, просто возвращают Radian:

public static Radian AngleBetween(Vector vector1, Vector vector2) 
{ 
    Radian radians = (Radian)AngleBetween(vector1, vector2); 

    return radians; 
} 

Или, если вы хотите вернуть IAngle, что будет работать тоже:

public static IAngle AngleBetween(Vector vector1, Vector vector2) 
{ 
    IAngle radians = (Radian)AngleBetween(vector1, vector2); 

    return radians; 
} 

Обобщения полезны, если что-то могут быть разных типов, но эта реализация посредством литья настаивает на использовании одного конкретного типа.

+0

О лучшем ответе, который этот пользователь собирается получить, поскольку вопрос в настоящее время стоит. – Jamiec

Смежные вопросы