Вы пробовали oCoords
/ aCoords
?
Это свойство должно возвращать все углы с применением поворота
http://fabricjs.com/docs/fabric .Rect.html # oCoords
http://fabricjs.com/docs/fabric.Rect.html#aCoords
Обновить [1115 ]
Поскольку вы хотите сохранить координаты для извлечения и отрисовки прямоугольника обратно из данных БД, я думаю, что лучше хранить не 4 угловые координаты, а слева, сверху, ширину, высоту, угол, масштаб. Так что вы можете создать прямоугольник в зависимости от этих свойств. Если вам это не нужно для использования в Fabricjs, вы можете использовать oCoords
, о котором я упоминал ранее.
Метод
getCoords
также позволяет использовать
Можно только бросить от базового класса до производного класса, если объект имеет на самом деле производный класс типа. Я имею в виду, Вы не можете бросить экземпляр основы (MyClass<int>
) к MyIntClass
. Вы можете, однако бросить его, если это на самом деле имело тип MyIntClass
сохраненный как MyClass<int>
экземпляр.
MyClass<int> foo = new MyIntClass();
MyIntClass bar = (MyIntClass)foo; // this works.
Примите:
class Base {
int x;
}
class Derived : Base {
int y;
}
Base foo = new Base();
Derived bar = (Derived)foo;
если было позволено, из чего был бы значение bar.y
быть? На самом деле, преобразование из Derived
кому: Base
не преобразование вообще. Это просто говорит компилятору позволять переменной типа Base
указать на объект типа Derived
. Это возможно, так как получено имеет больше или равные функции, чем Base
который не имеет место в наоборот.
Если бы Вы смогли создать оператор преобразования между основой и производными классами, то компилятор C# не мог бы отличить ее от созданного в отношениях, определенных для них. Поэтому Вы не можете создать операторы броска вдоль иерархий наследования.
Другие ответы до сих пор корректны, но я хотел бы указать, что Ваш пример не имеет никакого отношения к дженерикам. Это - эквивалент:
using System;
class Base {}
class Child : Base {}
class Test
{
static void Main()
{
Base b = new Base();
// This will throw an exception
Child c = (Child) b;
}
}
Как был сказан, Вы пытаетесь бросить объект в тип, из которого он не происходит. Сделал Вас, возможно, хотят сделать это:
MyClass<int> sth = new MyIntClass(10);
MyIntClass intsth = (MyIntClass) sth;
В комментариях Вы спросили:
Но почему преобразование из базового класса не позволяется?
Простой - это не имело бы никакого смысла. Рассмотрите пример:
class BaseClass
{
public int x;
public BaseClass(int StartX)
{
this.x = StartX;
}
}
class ChildClass: BaseClass
{
public int Y;
public BaseClass(int StartX, StartY): base(StartX)
{
this.y = StartY;
}
}
class Program
{
public static void Main()
{
BaseClass B = new BaseClass(3);
ChildClass C = (ChildClass)B;
Console.WriteLine(C.y);
}
}
Что Вы предполагаете, что эта программа произвела бы, предположив, что бросок работал? Еще хуже - воображают это BaseClass
имеет два дочерних класса - ChildClassA
и ChildClassB
. Вы хотите, чтобы это работало?
ChildClassA = новый ChildClassA (); BaseClass до н.э = (Базовый класс) A; ChildClassB B = (ChildClassB) до н.э;
Это эффективно позволило бы бросать ChildClassA
экземпляры к ChildClassB
- полностью неправильно.
Как указанный Mehrdad, Вы не можете удрученный объект. Upcasting неявен, поэтому Вы не можете перезаписать его.
Что касается неявного оператора, можно все еще создать конструктора в производном классе, который получает параметр базового класса типа.
Если необходимо бросить свободно, определить переменную как базовый класс, но инстанцировать производных классов.
Вместо того, чтобы создать MyIntClass, попробуйте псевдоним:
using MyClass<int> = What.Ever.Namespace.MyIntClass;
Это теперь допустимо:
MyClass<int> foo = new MyClass<int>();
MyIntClass bar = (MyIntClass)foo;
Просто поймите это при выполнении using
псевдоним, необходимо квалифицировать пространство имен на имени типа псевдонима (Что. Когда-либо. Пространство имен).
Относительно Вашего второго вопроса:
Но почему я не могу создать пользовательские преобразования из базового класса?
Ну, предположите, что у Вас есть этот сценарий
class Base {
}
class Derived {
public static operator Derived(Base b) { ... }
}
и Вы пытались сделать это
Base x = new Derived();
Derived y = (Derived)x;
преобразование нужно назвать?Конечно, нет! Значение внутри x
на самом деле имеет тип Derived
, таким образом, бросок является прямым без преобразования. Но если значение не имело типа Derived
, но бетон Base
, затем пользовательское преобразование должно произойти, потому что иначе у нас была бы ошибка компилятора. Это все не имеет никакого смысла; пользовательские преобразования найдены во время компиляции и тип значения x
только известен во времени выполнения. Поэтому компилятор не знал бы, что сделать - называют пользовательское преобразование или просто бросают значение...
Надежда это имеет немного смысла Вам.
Ответ на последнее редактирование.
Этот код действительно уже компилирует, он только перестал работать во времени выполнения:
MyIntClass intsth = (MyIntClass) sth;
Так, следующий оператор броска был бы избыточен, если оставлено явный:
общедоступный статический неявный оператор MyIntClass (MyClass myClass)
Так, компилятор должен препятствовать тому, чтобы Вы добавили то преобразование. Я думаю, что ошибка могла бы сбивать с толку, но я думаю, что она просто запрещает класс B преобразования классу A, если B получен из (предупреждение, казалось, мне предотвратило любое преобразование в A, сначала).
Если оператор сделан неявным, это также опасно, потому что downcasting может всегда перестать работать, таким образом, Вы имеете к:
Назначение / преобразование базового класса в производный класс имеет смысл, если вы считаете, что назначение или преобразование Копия значения по значению. Что смущает в C # для newbies - это непоследовательный способ:
int i = 5; // <- this creates an int.
int j = i; // <- this creates another int and copies the value of i into j.
Object a; // <- this does not create a copy of 'Object', only a reference to one
Object b = new Object(); // <- this actually creates an Object
a = b; // <- this sets the reference to an object a to the reference to an object b.
// both of them reference the same Object. No values were copied.
Если он делал копию значений, то копировал в базовый класс производный класс будет Работа. C # не работает, как другие языки.
Я думаю, это может вас смущать.