2016-02-26 5 views
1

Я пытаюсь создать 2D-векторы, координаты которых являются общими (Vector2Dint, Vector2Dfloat и т. Д.), Чтобы облегчить некоторые математические операции. Я видел, что этот вопрос довольно близок к моему: Can't operator == be applied to generic types in C#?, но мой случай с оператором «*». В принципе мне нужно сделать некоторые математические функции, такие как «крест» или «точкой» для этого вектора, один пример этого:Операторы общих типов

public static T cross<T>(Vec2<T> u, Vec2<T> v) 
    { 
     return u.x * v.y - u.y * v.x; 
    } 

Дело в Visual Studio говорит мне один и тот же: «Оператор„*“не может быть применяется к операндам типа «T» и «T» (T - тип координаты). Моя мысль была перегружать «*» оператор внутри класса «vec2», чтобы быть в состоянии умножить эти координаты, имея это:

public static Vec2<T> operator *(T x, T y) 
    { 
     return x * y; 
    } 

Но Visual Studio снова говорит мне то же самое. Я уверен, что я не перегружаю операторов правильно, но я не знаю причины. Спасибо за помощь.

EDIT 1: Хорошо, так что мы можем узнать из этого, если вы хотите определить функцию для разных типов (int, float, double и т. Д.) И хотите производительность, лучший способ сделать это - определить функцию для каждого типа, но теперь для меня возникает другая проблема. Если у вас очень длинная функция или несколько длинных функций, ¿это все еще лучший способ?

+0

Вы не знаете, что такое x и y, что заставляет вас думать, что у них есть оператор '*'? – Powerlord

+0

http://stackoverflow.com/a/9486094/3922214 –

+0

Хорошо, T неверно, если вы определили Vec2 , тогда ваш оператор будет для двух целых чисел, и вы хотите размножать векторы, а не два целых числа, я прав? – Gusman

ответ

0

Вы получаете эту ошибку, потому что тип «Т», неизвестно. Насколько вам известно, это может быть строка или любой класс или структура.

Один из способов сделать это, чтобы обеспечить перегрузку для всех «ожидаемых» типа вектора

public static int cross(Vec2<int> u, Vec2<int> v) 
    { 
     return u.x * v.y - u.y * v.x; 
    } 

    public static double cross(Vec2<double> u, Vec2<double> v) 
    { 
     return u.x * v.y - u.y * v.x; 
    } 

    public static long cross(Vec2<long> u, Vec2<long> v) 
    { 
     return u.x * v.y - u.y * v.x; 
    } 

    public static float cross(Vec2<float> u, Vec2<float> v) 
    { 
     return u.x * v.y - u.y * v.x; 
    } 

    ... 
+0

Я думаю, что это лучший способ сделать это, если ожидаемые типы всего лишь 4, я могу справиться с этим. – dolm

+0

@daolmed Это ваше решение, достаточно ли 4 типа или нет. В .net есть более десятка числовых типов .net – TKharaishvili

0

В настоящее время невозможно сообщить компилятору, какие операторы могут использоваться для параметров типового типа. Вопрос о расширении общих ограничений несколькими способами обсуждается на github in the C# compiler repository под абзацем под названием Интересно, но требуется поддержка CLR.

Вы также можете проголосовать за эту функцию, чтобы добавить на Visual Studio Uservoice

0

Ну, вот это действительно некрасиво способ сделать это, я никогда бы не использовать его для игры (скорость), но это acomplishes, что вы просили:

Ваш vec2 класс:

public class Vec2<T> 
    { 
     public T x; 
     public T y; 

     public static Vec2<T> operator *(Vec2<T> u, Vec2<T> v) 
     { 
      return u.Cross(v); 
     } 
    } 

а класс расширение:

public static class Exts 
    { 
     public static T Cross<T>(this Vec2<T> u, Vec2<T> v) 
     { 

      if (u.x is double) 
       return (T)Convert.ChangeType(Convert.ToDouble(u.x) * Convert.ToDouble(v.y) - Convert.ToDouble(u.y) * Convert.ToDouble(v.x), typeof(T)); 
      else if (u.y is float) 
       return (T)Convert.ChangeType(Convert.ToSingle(u.x) * Convert.ToSingle(v.y) - Convert.ToSingle(u.y) * Convert.ToSingle(v.x), typeof(T)); 
      else if (u.x is decimal) 
       return (T)Convert.ChangeType(Convert.ToDecimal(u.x) * Convert.ToDecimal(v.y) - Convert.ToDecimal(u.y) * Convert.ToDecimal(v.x), typeof(T)); 
      else 
       return (T)Convert.ChangeType(Convert.ToInt32(u.x) * Convert.ToInt32(v.y) - Convert.ToInt32(u.y) * Convert.ToInt32(v.x), typeof(T)); 

     } 
    } 
+0

Большое вам спасибо за ответ, но вы были правы, это для игры! – dolm

+0

Тогда мои два цента, НИКОГДА не используйте generics для игр, и меньше в случае, таком как класс Vector, поскольку у вас их тысячи, и они медленнее прямых. – Gusman

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