Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > VS 2008 struct Bug


Автор: Jlekc 21.7.2008, 13:02
Странный баг. В VS2005 в консуль этот код выдает разные значения. И это вроде нормально
В VS2008 проект работал нормально, но на каком-то этапе начал глючить. 
Упростил код до ниже привиденного. Структура передалась по ссылки((.
Мож кто натыкался, подскажите как это лечиться.
Код

struct Test
    {
        public static void Method(Test t)
        {
            Console.WriteLine(t.GetHashCode()); ;
        }
    }

    static class Program
    {

        [STAThread]
        static void Main(string[] args)
        {
            Test t = new Test();
            Console.WriteLine(t.GetHashCode());
            Test.Method(t);
            Console.ReadLine();
        }
    }

Автор: Jlekc 21.7.2008, 13:19
В продолжение глюков: 
Код

struct Test
    {
        public string Name;

        public static void Method(Test t)
        {
            Debug.WriteLine(t.GetHashCode()); ;
        }
    }

    static class Program 
    {
        
        [STAThread]
        static void Main()
        {
            Test t = new Test();
            Debug.WriteLine(t.GetHashCode()); // out: 18317060
            t.Name = "1";
            Debug.WriteLine(t.GetHashCode()); // out: -857880437

            Test.Method(t); // out: -857880437
        }
    }


почему 1 и 2 вывод отличаеться, а 3 совпадает с 2??

Автор: HalkaR 21.7.2008, 13:20
Не совсем понимаю - в чем проблема? Да хэш всегда одинаковый и это правильно.

Добавлено через 59 секунд
В чем проблема то - поменял значение, поменялся и хэш.

Автор: Jlekc 21.7.2008, 13:22
Хеш должен дать в данном случае адресс размешения?

Проблема в том что структура передалась по ссылке, в методе были модификации ее полей. И значит оригинальная структура тоже изменилас.
Я этого не ожидал, причем раньше все было нормально.

Автор: Idsa 21.7.2008, 13:23
Jlekc, дело в том, что метод GetHashCode, который структура наследует у Object, возвращает Hash на основании полей. Т. к. у двух этих структур нет полей, то возвращаются одинаковые хэши.
Вот немного модифицированный пример и первого поста:
Код

  internal struct Test
  {
    public int a;
    public static void Method(Test t)
    {
      t.a = 1;
      Console.WriteLine(t.GetHashCode());
      
    }
  }
 
  public static class Program
  {
    public static void Main(string[] args)
    {
      Test t = new Test();
      t.a = 0;
      Console.WriteLine(t.GetHashCode());
      Test.Method(t);
      Console.ReadLine();
    }
  }

Здесь хэши различаются на 1. Если изменить значения параметров, хэши изменятся.

Добавлено @ 13:25
Цитата(Jlekc @  21.7.2008,  17:19 Найти цитируемый пост)
почему 1 и 2 вывод отличаеться, а 3 совпадает с 2??

Потому что в первый раз Name равен пустой строке, а во 2-й и 3-й разы - "1".

Автор: HalkaR 21.7.2008, 13:29
Цитата(Jlekc @  21.7.2008,  13:22 Найти цитируемый пост)
Хеш должен дать в данном случае адресс размешения?

Хэш ни в каком случае не возвращает адрес размещения. Первое, это небезопасно, второе - бесполезно. Хэш даже в простейшем случае генерируется на основе данных в объекте.
Цитата(Jlekc @  21.7.2008,  13:22 Найти цитируемый пост)
Проблема в том что структура передалась по ссылке, в методе были модификации ее полей.

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

Автор: Jlekc 21.7.2008, 13:39
Ну ладно с хешем еще понятно.
А почему такое поведение:
Код

truct Test
    {
        public int[] Data;

        public Test(int Size)
        {
            this.Data = new int[Size];
        }

        public static void Method(Test t)
        {
            t.Data[0] = 2;
        }
    }

    static class Program 
    {
        
        [STAThread]
        static void Main()
        {
            Test t = new Test(1);
            t.Data[0] = 1;
            Test.Method(t);
            Debug.WriteLine(t.Data[0]); // 2
            Console.ReadLine();
        }
    }

Автор: HalkaR 21.7.2008, 13:47
Потому что массив - это ссылочный тип. При передаче объекта Test в метод он (объект Test) копируется, но ссылка на массив остается таже.

Автор: Jlekc 21.7.2008, 13:56
Цитата(HalkaR @  21.7.2008,  13:47 Найти цитируемый пост)
При передаче Test в метод он копируется, но ссылка на массив остается таже. 

Я думал что слово копируеться означает и копирование полей.
Для того чтоб не повредить оригинал заниматься ручным копирование полей? Но это криво.

Автор: Idsa 21.7.2008, 13:58
Цитата(Jlekc @  21.7.2008,  17:56 Найти цитируемый пост)
Я думал что слово копируеться означает и копирование полей.

Так оно и есть. Просто в этом поле хранится не массив, а ссылка на него. Она и копируется.

Автор: HalkaR 21.7.2008, 13:58
Цитата(Jlekc @ 21.7.2008,  13:56)
Цитата(HalkaR @  21.7.2008,  13:47 Найти цитируемый пост)
При передаче Test в метод он копируется, но ссылка на массив остается таже. 

Я думал что слово копируеться означает и копирование полей.
Для того чтоб не повредить оригинал заниматься ручным копирование полей? Но это криво.

Такова жизнь smile

Автор: Jlekc 21.7.2008, 14:01
Цитата(HalkaR @  21.7.2008,  13:58 Найти цитируемый пост)
Такова жизнь smile 

 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)