LINUX.ORG.RU

Type casting в C#

 ,


1

3

C#:

using System;
using System.Collections.Generic;

public  class ICantEvenNameClassAsMainBecauseCSSucks
{

    public static void Main(string[] args)
    {
        body.Add("lol", 4);
        Console.WriteLine("C# гавно! {0}", get("lol", 0L));
    }

    private static Dictionary<string, object> body = new Dictionary<string, object>();


    public static  T get<T>(string key, T defaultValue)
    {
        object o;
        if (body.TryGetValue(key, out o))
        {
            return (T) o;
        }
        else
            return defaultValue;
    }
}
out:
Unhandled Exception:
System.InvalidCastException: Cannot cast from source type to destination type.
  at IEvenCantNameClassAsMainBecauseCSSucks.get[Int64] (System.String key, Int64 defaultValue) [0x00000] in <filename unknown>:0 
  at IEvenCantNameClassAsMainBecauseCSSucks.Main (System.String[] args) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidCastException: Cannot cast from source type to destination type.
  at IEvenCantNameClassAsMainBecauseCSSucks.get[Int64] (System.String key, Int64 defaultValue) [0x00000] in <filename unknown>:0 
  at IEvenCantNameClassAsMainBecauseCSSucks.Main (System.String[] args) [0x00000] in <filename unknown>:0 

Java:

import java.util.*;

public class Main
{
    private static Map<String, Object> body = new HashMap<>();

    public static void main(String... args)
    {
        body.put("lol", 4);
        System.out.printf("Java получше! %d\n", get("lol", 0L));
    }

    public static <T> T get(String key, T defaultValue)
    {
        Object o;
        if (body.containsKey(key))
            {
                o = body.get("lol");
                return (T) o;
            }
        else
            {
                return defaultValue;
            }
    }
}

out:

Java получше! 4

тут даже нечего комментировать

★★★★

public class IEvenCantNameClassAsMainBecauseCSSucks()

Разве такое скомпилируется? Что за скобки после названия класса? Или это что новое в С# 5.0? Если это даже не компилируется, то автор обосрался.

AntonK ()
Ответ на: комментарий от AntonK

Разве такое скомпилируется?

Нет, только что проверил. Алсо, если сделать body.put(«lol», 4L); то всё работает, то что C# при unboxing не даёт привести один значимый тип к другому это прямо вот фатальный недостаток, ага.

Opxocc ()

Констатируется фатальное повреждение мозга жабой.

Да, Жаба не умеет нормальные Жденерики.

grim ★★★★ ()
Последнее исправление: grim (всего исправлений: 1)
Ответ на: комментарий от AntonK

а, не. Не скомпилится. Я что-то не так написал, скобки не нужны. Но дело не в этом же.

pashazz ★★★★ ()
Ответ на: комментарий от pashazz

С++, С#

В Java type erasure т.е. в рантайме дженериков нет, т.е. это синтаксический сахарок.

grim ★★★★ ()
Ответ на: комментарий от grim

а, это я знаю. Ну с крестами вообще не стоит сравнивать. А вот в шарпе дженерики похерены (для десериализации данных, например, структура которых заранее неизвестна) из-за проблемы, которую я проиллюстрировал

pashazz ★★★★ ()
Ответ на: комментарий от grim

вот если бы в C# не было бы означенной проблемы, было бы почти идеально. Осталось бы только заиметь кроссплатформенную стабильную используемую всеми реализацию гуя

pashazz ★★★★ ()
Ответ на: комментарий от pashazz

Но дело не в этом же.

Естественно.
Вам не дали привести long к string

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

А затем плеваться на пользователей ЯП с динамической типизацией, так как у них нет проверки типа и вам будут верить :)

grim ★★★★ ()
Ответ на: комментарий от grim

long к string действительно плохо! А вот long к int (что и происходит) должно таки приводить (по здравому смыслу). Но не приводит

pashazz ★★★★ ()
Ответ на: комментарий от grim

а как еще сделать коллекцию из неизвестных заранее объектов?

pashazz ★★★★ ()
Последнее исправление: pashazz (всего исправлений: 1)
Ответ на: комментарий от pashazz

Невнимательно код читал.

long к int не должно разрешать приводить без явного указания, так как чревато проблемами, для решения которых потом приходится нанимать специалистов которым платят в разы больше чем оригинальных разработчикам.

Сталкивался лично.

grim ★★★★ ()

Проблема не в Type-casting-е, а в boxing/unboxing-е. Unbox-ить тип значения в C# можно только точно к тому-же типу, что и был «забоксен». А вы box-ите int, а unbox-ить пытаетесь long.

qrck ★★ ()
Ответ на: комментарий от grim

да тут проблема не в этом даже... даже если int и long тут местами поменять - результат один

pashazz ★★★★ ()
Ответ на: комментарий от pashazz

Забавно.
Не сталкивался. ОЧЕНЬ давно не хранил object.

Но в данном случае .Net прав.

Вы же можете написать
body.Add(«lol», «xxx»);
а затем
Console.WriteLine(«отлов идиотов {0}», get(«lol», 0L));

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

grim ★★★★ ()
Последнее исправление: grim (всего исправлений: 1)
Ответ на: комментарий от pashazz

У явы и другие недостатки есть, помимо того, что это там работает :)

Вообще, если вы совсем не уверены, что там будет - используйте dynamic.

qrck ★★ ()

ну вообще-то ты сам себе заботливо разложил грабли и наступил на них, причем в обоих ЯП.

maloi ★★★★★ ()

Добавлю в букмарки, чтобы демонстрировать как пример в назидание :)

grim ★★★★ ()

В Java жденерики не совсем «нормальные». У нас type erasure и в рантайме все плюшки теряются. Алсо, говорят, в C# есть синтаксический сахар типа new T(). Не сказать, чтобы часто приходилось пользоваться рефлексией, по понятным причинам, но как минимум выглядит удобно.

P.S.: я не джавахейтер, как раз наоборот. P.P.S:

4
0L

Это не ошибка, специально int и Long?

bytecode ★★ ()
Ответ на: комментарий от bytecode

Это он специально.

Чтобы можно было засунуть int а достать long

Или засунуть string а достать long.

причём в Java первый вариант проходит и рантайм выдаст ошибку только при втором а в C# в обеих случаях будет ошибка, от чего pashaz посчитал Java лучше.

grim ★★★★ ()
Ответ на: комментарий от grim

в мыслях не было string засунуть и long отдать. Это идиотизм же, ни в каком языке нельзя скастовать так. Я говорю только о типах, которые кастуются между собой

pashazz ★★★★ ()
Ответ на: комментарий от pashazz

ниче, грабли говорю разложил и сам на них наступил.

maloi ★★★★★ ()
Ответ на: комментарий от pashazz

Если ты не видишь где грабли в коде на Джаве - приведи код к такому виду

Long l = get("lol", 0L);
System.out.printf("Java получше! %d\n", l);
и убедись, что Integer в Long в джаве не кастуется, а тебе просто повезло.

maloi ★★★★★ ()
Ответ на: комментарий от pashazz

Я говорю только о типах, которые кастуются между собой

Я могу на это только огорченно нахмуриться.

grim ★★★★ ()
Ответ на: комментарий от pashazz

Я говорю только о типах, которые кастуются между собой
шаблонно-дженериковый код

нет, серьёзно?

next_time ★★★★ ()
Ответ на: комментарий от next_time

Json парсер по религиозным причинам все в long кастует.

pashazz ★★★★ ()
Ответ на: комментарий от next_time

ну вот это обертка над ним, он все числа кидает в long и в словарь объектов

pashazz ★★★★ ()

Феерический быдлокод. У нас за такое увольняют сразу.

soslow ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.