expected System.ComponentModel.INotifyPropertyChanged, got object in type-enforced expression: System.Object is not a subtype of System.ComponentModel.INotifyPropertyChanged [simple require]
V>expected System.ComponentModel.INotifyPropertyChanged, got object in type-enforced expression: System.Object is not a subtype of System.ComponentModel.INotifyPropertyChanged [simple require]
V>Что не так?
двоеточие это уточнение типа, хинт компилятору, примерно как приведение типов в таком c# коде:
var x = (object)(new List<int>());
если те нужно небезопасное приведение типов с проверкой в рантайм, то нужно использовать оператор :>
Здравствуйте, Visor2004, Вы писали:
V>Здравствуйте, Jack128, Вы писали:
J>>если те нужно небезопасное приведение типов с проверкой в рантайм, то нужно использовать оператор :>
V>Я не хочу писать обработку для InvalidCastException
V>expected System.ComponentModel.INotifyPropertyChanged, got object in type-enforced expression: System.Object is not a subtype of System.ComponentModel.INotifyPropertyChanged [simple require]
V>expected System.ComponentModel.INotifyPropertyChanged, got object in type-enforced expression: System.Object is not a subtype of System.ComponentModel.INotifyPropertyChanged [simple require]
V>Что не так?
Подозреваю что тебе тут проверять на null даже не требуется:
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Visor2004, Вы писали:
V>>получить null в переменной в случае несовместимости типов
Z>К своему стыду не знаю, есть ли в Nemerle аналог оператора as.
Здравствуйте, Visor2004, Вы писали:
V>И уж точно намного больше, чем то, что насоветовали гуру выше, с иcпользованием pattern matching.
ПМ это обычный способ работы с типами выражений, и он значительно удобнее as:
1) связывает имя
2) защищает от null
3) позволяет выполнять множественную диспетчеризацию
match (dataContext)
{
| propertyChanged is INotifyPropertyChanged =>
propertyChanged.PropertyChanged += ( s, e ) => when ( e.PropertyName == property ) PropertyChanged ( s, e.PropertyName );
| _ => ()
}
1. В контексте не создается мусорная переменная (к тому же не гарантировано инициализированная)
2. Условие выполнения кода читается как propertyChanged is INotifyPropertyChanged, а не как безликое propertyChanged != null
3. Если тебе придется дополнить код действиями с другим, возможно реализуемым интерфейсом, сделать это будет гораздо проще
Теперь расскажи, чем тебе нравится больше вариант с приведением и проверкой на нулл, я не могу найти ни одной причины.
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Visor2004, Вы писали:
V>>мне не нравится то, что он раздувает код
Z>а ты сравнивал? они абсолютно одинаковы по длине.
Самому, когда был молодым не нравилось что нету as-a а сейчас понял что матч в разы круче и скучаю в шарпе за матчем. Матч написать гораздо проще!! так как авто дополнение и все такое, а так надо кастонуть, потом с нулом сравнить.
Здравствуйте, VladD2, Вы писали:
VD>Это баг в дизайне языка
Если в языке нету патерн матчинга и использовать по назначению а не (a as B).SomeMethod();
ТО думаю вполне таки нормально,например сначала ез а поом проверка на нул.. хотя с патерн мачингом намного удобнее, но в шарпе же нету патерн мачинга)
з.ы. as таки быстре чем патерн матичнг.
з.ы.ы. is и as генрируют один и тот же MSIL опкод )
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, BogdanMart, Вы писали:
BM>>з.ы. as таки быстре чем патерн матичнг.
H>Измерения скорости в студию.
Таки не не на много меделенне (и меня это радует!!!)
matched for 3819
ased for 3530
Так-что хоть оно и медленне, но удовлетворительно.
Тестовый код:
public class Class1 : ITester
{
public Test(lst : array[CommonClasses.Base]) : void
{
foreach (b in lst)
{
| b is D1=> b.d1()
| b is D2=> b.d2()
}
}
}
public class Class1 : ITester
{
public void Test(Base[] lst)
{
foreach (var b in lst)
{
var d1 = b as D1;
if (d1 != null)
{
d1.d1();
continue;
}
var d2 = b as D2;
if (d2 != null)
d2.d2();
}
}
}
//------------------------public interface ITester
{
void Test(Base[] lst);
}
public abstract class Base { }
public class D1 : Base
{
public void d1() { }
}
public class D2 : Base
{
public void d2() { }
}
Здравствуйте, BogdanMart, Вы писали:
BM>Таки не не на много меделенне (и меня это радует!!!) BM>
BM>matched for 3819
BM>ased for 3530
BM>
BM>Так-что хоть оно и медленне, но удовлетворительно.
Там разница определяется тем, что паттерн:
def o = "test" : object;
match (o)
{
| x is string => WriteLine(x)
| _ => ()
}
переписывается в:
object o = "test";
if (o is string)
{
string x = (string) o;
Console.WriteLine(x);
}
В принципе, можно подшаманить оптимизацию, чтобы код переписывался в аналогичный as-овскому коду генерируемому шарпом.
Вот только на практике эту разницу в микроскоп не заметишь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Visor2004, Вы писали:
V>короче, говоря по русски, мне надо аналог "as" из C#
as — это грабли заложенные в C#. Тянуть их в Nemerle никто не будет. Учись пользоваться паттерн-матчингом. А еще лучше изучи подходы к проектированию принятые в Nemerle. Обычно там где в C# требуются динамические приведения типов в Nemerle используются варианты и паттерн-матчинг.
Лучше опиши саму задачу, а тебе подскажут как ее лучше решать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, BogdanMart, Вы писали:
VD>>Это баг в дизайне языка
BM>Если в языке нету патерн матчинга и использовать по назначению а не (a as B).SomeMethod();
Язык должен стараться предотвращать использование фичи не по назначению. А as наоборот, косвенно поощряет неверное использование.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Язык должен стараться предотвращать использование фичи не по назначению. А as наоборот, косвенно поощряет неверное использование.
Resharper ругается на эту штуку а то что в Шарпах много непонятных мест, на которых многие попадаются это да.
С другой стороны замыкания тоже создают много побочных эффектов, например то что переменная используемая в замыкании может измениться.
int a = 6;
var enumerable = lst.Where(i => i > a);
a = 500;
var arr = enumerable.ToArray();
и немерле от такого не застрахован, хотя тут язык сам подталкивает на использование иммутабельных переменных и это упростит этот момент, но все же.
(В яве запрещено использовать в замыканиях мутабельные переменные, но все же иногда и надо)
Здравствуйте, BogdanMart, Вы писали:
BM>Resharper ругается на эту штуку
А что в этом смешного? Если Resharper распознает паттерн неверного использования и сообщает об этом, то это замечательно и честь и хвала решарперу (и горе тем кто пишет на шарпе без решарпера и при этом сам не дорос до понимания граблей оператора as).
BM>а то что в Шарпах много непонятных мест, на которых многие попадаются это да.
Много? Вообще-то в шарпе таких мест как раз не много. И это заслуга дизайнеров языка.
BM>С другой стороны замыкания тоже создают много побочных эффектов, например то что переменная используемая в замыкании может измениться.
Само по себе это не проблема. Но так же есть паттерны неверного использования (типа создания лямбды в циклах с захватом переменной цикла) — это да.
BM>
BM>int a = 6;
BM>var enumerable = lst.Where(i => i > a);
BM>a = 500;
BM>var arr = enumerable.ToArray();
BM>
BM>и немерле от такого не застрахован, хотя тут язык сам подталкивает на использование иммутабельных переменных и это упростит этот момент, но все же.
Здесь вообще нет проблемы. Нужно только четко знать семантику метода Where. Дело именно в нем, так как он производит вычисления отложено.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Visor2004, Вы писали:
V>Здравствуйте, Visor2004, Вы писали:
V>короче, говоря по русски, мне надо аналог "as" из C#
А почему ты называешь его не безопасным приведением? По моему решарпер его именует таки Safe Cast (так как не бросает исключение)
А небезопасное это:
.locals init (
[0] class [CommonClasses]CommonClasses.Base b,
[1] class [CommonClasses]CommonClasses.D1 d1)
ldloc.0
stloc.1//СОбсвнноэтои весь каст
//теперь можно вызвать метод
L_0021: ldloc.1
L_0022: callvirt instance void [CommonClasses]CommonClasses.D1::d1()
// собственно можно было загрузить нулевой и вызвать метод, но такая наглость уже может не понравиться JITC'y
И МСИЛ таки позволяе ттакое делать, абсолютно без никаких проверок на тип, просто присвоить, а потом если тип не правильный сам борись с падениями VM.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, BogdanMart, Вы писали:
VD>А что в этом смешного?
Я не подрозумева лкатующийся по полу смайл. ПРосто не знаю как здесьь они розставляються
VD>Нужно только четко знать семантику метода Where. Дело именно в нем, так как он производит вычисления отложено.
На моем опыте многие знакомые ее не знают(хоть там явно написано в справке) и та же история с езом.
Здравствуйте, BogdanMart, Вы писали:
BM>На моем опыте многие знакомые ее не знают(хоть там явно написано в справке) и та же история с езом.
Согласись это разные ситуации. Одно дело не знать семантику функции и делать из-за этого ошибки. А другое пользоваться оператором языка и нарываться на грабли.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Согласись это разные ситуации. Одно дело не знать семантику функции и делать из-за этого ошибки. А другое пользоваться оператором языка и нарываться на грабли.
Результат тот же. Хотя по моему если что то используешь (будь то оператор или функция) надо иметь хоть какое то представление о том как оно работает.
Здравствуйте, BogdanMart, Вы писали:
BM>Результат тот же. Хотя по моему если что то используешь (будь то оператор или функция) надо иметь хоть какое то представление о том как оно работает.
Проблема as в том, что те кто его используют обычно уверены, что понимают его поведение. Они просто свято уверены, что в этом то месте null появиться не может. А язык провоцирует на использование as, так как штатное приведение типов довольно неуклюжее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Проблема as в том, что те кто его используют обычно уверены, что понимают его поведение. Они просто свято уверены, что в этом то месте null появиться не может. А язык провоцирует на использование as, так как штатное приведение типов довольно неуклюжее.