Небезопасное приведение типов
От: Visor2004  
Дата: 26.04.11 13:01
Оценка:
Не могу написать вот так:

    
    private ConnectToPropertyChanged ( property : string, dataContext : object ) : void
    {
      def propertyChanged = dataContext : INotifyPropertyChanged;
    }


ругаеццо двоеточие в объявлении переменных.

expected System.ComponentModel.INotifyPropertyChanged, got object in type-enforced expression: System.Object is not a subtype of System.ComponentModel.INotifyPropertyChanged [simple require]


Что не так?
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re: Небезопасное приведение типов
От: Jack128  
Дата: 26.04.11 13:06
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>Не могу написать вот так:


V>
    
V>    private ConnectToPropertyChanged ( property : string, dataContext : object ) : void
V>    {
V>      def propertyChanged = dataContext : INotifyPropertyChanged;
V>    }

V>


V>ругаеццо двоеточие в объявлении переменных.


V>

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>());


если те нужно небезопасное приведение типов с проверкой в рантайм, то нужно использовать оператор :>
Re[2]: Небезопасное приведение типов
От: Visor2004  
Дата: 26.04.11 13:21
Оценка:
Здравствуйте, Jack128, Вы писали:

J>если те нужно небезопасное приведение типов с проверкой в рантайм, то нужно использовать оператор :>


Я не хочу писать обработку для InvalidCastException
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[3]: Небезопасное приведение типов
От: Jack128  
Дата: 26.04.11 13:23
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>Здравствуйте, Jack128, Вы писали:


J>>если те нужно небезопасное приведение типов с проверкой в рантайм, то нужно использовать оператор :>


V>Я не хочу писать обработку для InvalidCastException


а чего хочешь?
Re[4]: Небезопасное приведение типов
От: Visor2004  
Дата: 26.04.11 13:27
Оценка:
Здравствуйте, Jack128, Вы писали:

J>а чего хочешь?


получить null в переменной в случае несовместимости типов
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re: Небезопасное приведение типов
От: Visor2004  
Дата: 26.04.11 13:35
Оценка:
Здравствуйте, Visor2004, Вы писали:

короче, говоря по русски, мне надо аналог "as" из C#
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[5]: Небезопасное приведение типов
От: Jack128  
Дата: 26.04.11 13:36
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>Здравствуйте, Jack128, Вы писали:


J>>а чего хочешь?


V>получить null в переменной в случае несовместимости типов


аналог as шарповского?? AFAIK — такого оператора нету, мибо макросом добавь, либо по месту


def propertyChanged = match (dataContext) { | x is INotifyPropertyChanged => x; | _ => null }
Re[5]: Небезопасное приведение типов
От: hardcase Пират http://nemerle.org
Дата: 26.04.11 13:38
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>Здравствуйте, Jack128, Вы писали:


J>>а чего хочешь?


V>получить null в переменной в случае несовместимости типов


На самом деле это неудачная практика, которую навязывает as-выражение C#.

def propertyChanged = match(dataContext)
{
  | x is INotifyPropertyChanged => x
  | _ => null
}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Небезопасное приведение типов
От: Ziaw Россия  
Дата: 26.04.11 13:38
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>получить null в переменной в случае несовместимости типов


К своему стыду не знаю, есть ли в Nemerle аналог оператора as.

Сам обычно юзаю такой паттерн:

match (dataContext)
{
| listener is INotifyPropertyChanged => listener.PropertyChanged(this, PropertyChangedEventArgs("prop"))
| _ => ();
}
Re: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 26.04.11 13:42
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>Не могу написать вот так:


V>
    
V>    private ConnectToPropertyChanged ( property : string, dataContext : object ) : void
V>    {
V>      def propertyChanged = dataContext : INotifyPropertyChanged;
V>    }

V>


V>ругаеццо двоеточие в объявлении переменных.


V>

V>expected System.ComponentModel.INotifyPropertyChanged, got object in type-enforced expression: System.Object is not a subtype of System.ComponentModel.INotifyPropertyChanged [simple require]


V>Что не так?


:> вместо :
Re: Небезопасное приведение типов
От: hardcase Пират http://nemerle.org
Дата: 26.04.11 13:43
Оценка: +1
Здравствуйте, Visor2004, Вы писали:

V>Не могу написать вот так:


V>
    
V>    private ConnectToPropertyChanged ( property : string, dataContext : object ) : void
V>    {
V>      def propertyChanged = dataContext : INotifyPropertyChanged;
V>    }

V>


V>ругаеццо двоеточие в объявлении переменных.


V>

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 даже не требуется:

private ConnectToPropertyChanged ( property : string, dataContext : object ) : void
{
  match(dataContext)
  {
    | x is INotifyPropertyChanged =>
      x.PropetyChanged += (_, e) =>
      {
         when(e.PropertyName == property)
         {
           ...
         }
      }
    | _ => () // ничего не делаем
  }
}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Небезопасное приведение типов
От: hardcase Пират http://nemerle.org
Дата: 26.04.11 13:46
Оценка: +3
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, Visor2004, Вы писали:


V>>получить null в переменной в случае несовместимости типов


Z>К своему стыду не знаю, есть ли в Nemerle аналог оператора as.


Этот оператор не нужен в Nemerle.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Небезопасное приведение типов
От: Visor2004  
Дата: 26.04.11 13:51
Оценка: -1 :)
Вот это мне нравится куда больше

      def propertyChanged = dataContext : INotifyPropertyChanged;
      when ( propertyChanged != null )
        propertyChanged.PropertyChanged += ( s, e ) => when ( e.PropertyName == property ) PropertyChanged ( s, e.PropertyName );


чем вот это

      try
      {
         def propertyChanged = dataContext :> INotifyPropertyChanged;
         propertyChanged.PropertyChanged += ( s, e ) => when ( e.PropertyName == property ) PropertyChanged ( s, e.PropertyName );
      }
      catch ( e : InvalidCastException )
      {

      }


И уж точно намного больше, чем то, что насоветовали гуру выше, с иcпользованием pattern matching.
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[3]: Небезопасное приведение типов
От: hardcase Пират http://nemerle.org
Дата: 26.04.11 14:07
Оценка: +1
Здравствуйте, Visor2004, Вы писали:

V>И уж точно намного больше, чем то, что насоветовали гуру выше, с иcпользованием pattern matching.


ПМ это обычный способ работы с типами выражений, и он значительно удобнее as:
1) связывает имя
2) защищает от null
3) позволяет выполнять множественную диспетчеризацию
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 26.04.11 14:08
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>Здравствуйте, Visor2004, Вы писали:


V>короче, говоря по русски, мне надо аналог "as" из C#+



По сути можно обойтись матчем, а можно написать свой макрос который реализует внутри матч.



macro @:- (exp1, exp2)
{
<[
match($exp1)
{
|$exp1 as $exp2 => $exp1
| _ => null;
}
]>
}
Re[4]: Небезопасное приведение типов
От: Visor2004  
Дата: 26.04.11 15:03
Оценка:
мне не нравится то, что он раздувает код
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[3]: Небезопасное приведение типов
От: Ziaw Россия  
Дата: 26.04.11 15:17
Оценка: +1
Здравствуйте, Visor2004, Вы писали:

V>Вот это мне нравится куда больше


V>
V>      def propertyChanged = dataContext : INotifyPropertyChanged;
V>      when ( propertyChanged != null )
V>        propertyChanged.PropertyChanged += ( s, e ) => when ( e.PropertyName == property ) PropertyChanged ( s, e.PropertyName );
V>


Давай сравним:
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. Если тебе придется дополнить код действиями с другим, возможно реализуемым интерфейсом, сделать это будет гораздо проще

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

P.S. Вариант с ловлей экзепшена — антипаттерн.
Re[5]: Небезопасное приведение типов
От: Ziaw Россия  
Дата: 26.04.11 15:18
Оценка: +1
Здравствуйте, Visor2004, Вы писали:

V>мне не нравится то, что он раздувает код


а ты сравнивал? они абсолютно одинаковы по длине.
Re[6]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 26.04.11 20:47
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, Visor2004, Вы писали:


V>>мне не нравится то, что он раздувает код


Z>а ты сравнивал? они абсолютно одинаковы по длине.


Самому, когда был молодым не нравилось что нету as-a а сейчас понял что матч в разы круче и скучаю в шарпе за матчем. Матч написать гораздо проще!! так как авто дополнение и все такое, а так надо кастонуть, потом с нулом сравнить.
Re[7]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.05.11 21:28
Оценка:
Здравствуйте, hardcase, Вы писали:

Z>>К своему стыду не знаю, есть ли в Nemerle аналог оператора as.


H>Этот оператор не нужен в Nemerle.


Он нигде не нужен. Это баг в дизайне языка (пруй линк
Автор(ы): Владислав Чистяков (VladD2)
Дата: 18.12.2004
Работая над открытыми проектами, автор заметил, что операторы as и is многими программистами зачастую используются ненадлежащим образом. Результатом очередного двухчасового поиска ошибки и стала эта статья.


).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 08:22
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Он нигде не нужен. Это баг в дизайне языка (пруй линк
Автор(ы): Владислав Чистяков (VladD2)
Дата: 18.12.2004
Работая над открытыми проектами, автор заметил, что операторы as и is многими программистами зачастую используются ненадлежащим образом. Результатом очередного двухчасового поиска ошибки и стала эта статья.


).


Ну давать пруф линк на свою же статью как то не особо круто
Re[8]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 08:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это баг в дизайне языка


Если в языке нету патерн матчинга и использовать по назначению а не (a as B).SomeMethod();
ТО думаю вполне таки нормально,например сначала ез а поом проверка на нул.. хотя с патерн мачингом намного удобнее, но в шарпе же нету патерн мачинга)

з.ы. as таки быстре чем патерн матичнг.
з.ы.ы. is и as генрируют один и тот же MSIL опкод )
Re[9]: Небезопасное приведение типов
От: hardcase Пират http://nemerle.org
Дата: 03.05.11 09:09
Оценка:
Здравствуйте, BogdanMart, Вы писали:

BM>з.ы. as таки быстре чем патерн матичнг.


Измерения скорости в студию.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[10]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 09:52
Оценка:
Здравствуйте, 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() { }
    }


Да и выглядит с матчем красивее.

Солюшен студии
Re[11]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 14:46
Оценка:
Здравствуйте, 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-овскому коду генерируемому шарпом.
Вот только на практике эту разницу в микроскоп не заметишь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 14:48
Оценка:
Здравствуйте, Visor2004, Вы писали:

V>короче, говоря по русски, мне надо аналог "as" из C#


as — это грабли заложенные в C#. Тянуть их в Nemerle никто не будет. Учись пользоваться паттерн-матчингом. А еще лучше изучи подходы к проектированию принятые в Nemerle. Обычно там где в C# требуются динамические приведения типов в Nemerle используются варианты и паттерн-матчинг.

Лучше опиши саму задачу, а тебе подскажут как ее лучше решать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 19:03
Оценка:
Здравствуйте, BogdanMart, Вы писали:

VD>>Это баг в дизайне языка


BM>Если в языке нету патерн матчинга и использовать по назначению а не (a as B).SomeMethod();


Язык должен стараться предотвращать использование фичи не по назначению. А as наоборот, косвенно поощряет неверное использование.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 19:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Язык должен стараться предотвращать использование фичи не по назначению. А as наоборот, косвенно поощряет неверное использование.


Resharper ругается на эту штуку а то что в Шарпах много непонятных мест, на которых многие попадаются это да.

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

int a = 6;
var enumerable = lst.Where(i => i > a);
a = 500;
var arr = enumerable.ToArray();

и немерле от такого не застрахован, хотя тут язык сам подталкивает на использование иммутабельных переменных и это упростит этот момент, но все же.
(В яве запрещено использовать в замыканиях мутабельные переменные, но все же иногда и надо)
Re[11]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 19:18
Оценка:
Здравствуйте, 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. Дело именно в нем, так как он производит вычисления отложено.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 19:19
Оценка:
Здравствуйте, 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.
Re[12]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 20:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, BogdanMart, Вы писали:


VD>А что в этом смешного?


Я не подрозумева лкатующийся по полу смайл. ПРосто не знаю как здесьь они розставляються

VD>Нужно только четко знать семантику метода Where. Дело именно в нем, так как он производит вычисления отложено.


На моем опыте многие знакомые ее не знают(хоть там явно написано в справке) и та же история с езом.
Re[13]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.05.11 20:55
Оценка:
Здравствуйте, BogdanMart, Вы писали:

BM>На моем опыте многие знакомые ее не знают(хоть там явно написано в справке) и та же история с езом.


Согласись это разные ситуации. Одно дело не знать семантику функции и делать из-за этого ошибки. А другое пользоваться оператором языка и нарываться на грабли.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 03.05.11 21:40
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Согласись это разные ситуации. Одно дело не знать семантику функции и делать из-за этого ошибки. А другое пользоваться оператором языка и нарываться на грабли.


Результат тот же. Хотя по моему если что то используешь (будь то оператор или функция) надо иметь хоть какое то представление о том как оно работает.
Re[15]: Небезопасное приведение типов
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.05.11 10:37
Оценка:
Здравствуйте, BogdanMart, Вы писали:

BM>Результат тот же. Хотя по моему если что то используешь (будь то оператор или функция) надо иметь хоть какое то представление о том как оно работает.


Проблема as в том, что те кто его используют обычно уверены, что понимают его поведение. Они просто свято уверены, что в этом то месте null появиться не может. А язык провоцирует на использование as, так как штатное приведение типов довольно неуклюжее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Небезопасное приведение типов
От: BogdanMart Украина  
Дата: 04.05.11 10:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Проблема as в том, что те кто его используют обычно уверены, что понимают его поведение. Они просто свято уверены, что в этом то месте null появиться не может. А язык провоцирует на использование as, так как штатное приведение типов довольно неуклюжее.


Таки да. В немерле по красивее будет )
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.