2017-01-23 2 views
0

У меня есть структура, которая выглядит следующим образом:C# Оператора Перегрузка Использования Подкласса Generic в

public struct Vector2d<T> where T : Unit { 
    public double x; 
    public double y; 

    ... 

    public static Vector2d<Length> operator * (Vector2d<Speed> speed, Vector2d<Duration> duration) { 
     return new Vector2d<Length>(speed.x * duration.x, speed.y * duration.y); 
    } 
} 

длиной, скорость и типы дюрации все подтипы группы. (Т наследует от блока, а)

Однако компилятор говорит:

One of the parameters of a binary operator must be the containing type.

Это кажется мне странным, потому что типы, предоставляемые являются подклассы содержащего типа.

Почему я пытаюсь сделать незаконным?

Я знаю, что Vector2 не является подклассом Vector2, но я не пытаюсь использовать значения типа generic. Все данные, используемые в операторе, - это класс Vector2.

+0

Это незаконно, потому что разработчики языка сделали это незаконным. Сообщение об ошибке сообщает вам точно ограничение, которое описывает спецификация C#. Компилятор просто следит за спецификацией. Если вы хотите знать «почему?» вам нужно спросить у дизайнеров языка, и даже тогда их рассуждения могут основываться главным образом на их собственном мнении. –

+0

Не знаете, почему этот вопрос был опущен ... совершенно правильный вопрос с кодом и четким вопросом. +1 от меня. – CodingYoshi

+0

Я рекомендую не пытаться представлять единичный анализ с помощью дженериков. Единицы - это то, что действительно нужно встроить в язык. См. Например, аннотации типа F #. https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/units-of-measure –

ответ

0

Согласно MSDN page для этой ошибки:

A definition of a binary operator specifies both parameters with types other than that of the class or structure in which the operator is defined. When you define an operator in a class or structure, at least one of the parameters must be of the type of that class or structure.

В вашем случае, ваш оператор не делает использование Vector2d<T> типа (вы используете Vector2d<Speed> и Vector2d<Duration>

+0

Таким образом, оператор должен применять ко всем экземплярам типа, а не только подмножество. Понял. – tbg10101

0

Операторы работают по инстанциям. типа, в котором они заявлены. Например:

string one = new string(new char[] { 'o', 'n', 'e' }); 
string two = new string(new char[] { 't', 'w', 'o' }); 
if (one == two) { // do something... }; 

Причина, по которой я могу помочь нам e == - это потому, что он реализован в классе String.

У вас также есть оператор в своем классе. Так что давайте использовать его. Но для этого мне нужно создать экземпляр Vector2d<T>, и поскольку он является открытым, мне нужно закрыть его во время создания экземпляра.

Так давайте сделаем это первая:

public class MyClass : Unit 
{ 
} 

Теперь давайте создадим экземпляр вашей структуры:

var inst1 = new Vector2d<MyClass>(); 
var inst2 = new Vector2d<MyClass>(); 

Это работает, потому что MyClass проходит ограничение, что T должен быть унаследован от Unit. Хорошо, теперь я собираюсь использовать оператор:

// Ooops MyClass is not Speed or Duration 
var result = inst1 * inst2; 

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

В вашем случае можно определить только оператор для Vector2d<T> как это:

public struct Vector2d<T> where T : Unit 
{ 
    public double x; 
    public double y; 

    public Vector2d(double x, double y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public static Vector2d<T> operator *(Vector2d<T> speed, Vector2d<T> duration) 
    { 
     return new Vector2d<T>(speed.x * duration.x, speed.y * duration.y); 
    } 
} 

Кроме того, ваш оператор, то, как вы его не родовой вообще. Он использует Speed, Duration и Length, поэтому вы работаете с этими типами.

Ошибка Одним из параметров двоичного оператора должен быть содержащийся тип. - способ компилятора избегать нас, попадая в такие неприятности. Мы должны быть благодарны!

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