Kilka pytań o struktury.

0

Do rzeczy.

  1. Nie mogę pojąć o co chodzi w zdaniu "direct array access via square-brackets and the field specifier dot. Note that, in .NET, arrays are a special and unique primitive of the Common Type System. As @Ani mentions above, this syntax cannot be used to change an individual field of a reference instance, such as a list, even when it is parameterized with a value-type."
    Źródło: http://stackoverflow.com/a/14277068

  2. List<T> w bebechach operuje na tablicy. Czy jednocześnie gwarantuje to, że elementy n, n+1, n+2 są ułożone obok siebie w pamięci?

  3. Czy mając tablice struktur i implementując własny IComparer podczas porównania elementów w grę będzie wchodził boxing?

1

Odpowiem na tyle ile wiem, przydalby sie tutaj @somekind czy @katelx

tlumaczac na polski o co chodzi w zdaniu
direct array access via square-brackets and the field specifier dot. Note that, in .NET, arrays are a special and unique primitive of the Common Type System. As @Ani mentions above, this syntax cannot be used to change an individual field of a reference instance, such as a list, even when it is parameterized with a value-type

Bezposredni dostep do tablicy za pomoca [] oraz pola za pomoca kropki. Zwroc uwage na to ze w .NET tablice sa specjalnym i unikalnym prymitywem z podstawowym typow w System. Jak Ani wspomnial powyzej, ten kod nie moze byc uzyty by zmienic pojedyncze pole jako referencje obiektu, jak na przyklad lista, nawet gdy jest to okreslony typ jako value

W C# mamy reference oraz value, value zawsze sa kopiowane a reference zawsze przekazywane bezposrednio. Na dobra sprawe to co robi, to C# juz to robi (jako ze obiekt jest typem referencyjnym oraz tablica takze). Musialbym sprawdzic jak to dziala na kompilatorze, ale wydaje mi sie ze do funkcji bedzie przekazana referencja obiektu, wiec nie ma sensu tam robic ref

  1. Nie ma nic w dokumentacji by zapewnial ze beda obok siebie. Wiec nie mozesz zalozyc ze beda obok siebie. Zapewne beda. Nie jestem pewien czy Ms udostepnil zrodla jezeli chodzi o System.Generics.Collection. Poszukaj na githubie i po prostu sprawdz ;) Chociaz dlaczego potrzebujesz by byly obok siebie? Mozna wiedziec co probujesz osiagnac?

  2. Z tego co pamietam to tak

0
fasadin napisał(a):

Zapewne beda. Nie jestem pewien czy Ms udostepnil zrodla jezeli chodzi o System.Generics.Collection. Poszukaj na githubie i po prostu sprawdz ;) Chociaz dlaczego potrzebujesz by byly obok siebie? Mozna wiedziec co probujesz osiagnac?

Tylko co w tym przypadku daje dostęp do źródeł?
Ułożeniem obiektów w pamięci zajmuje się CLR i GC, nie kod źródłowy. Tablica sama w sobie też nie gwarantuje sposobu ułożenia obiektów.

0

Przepraszam za zwłokę, ale byłem na działce a tam komputer przegrywa z naturą ;)

fasadin napisał(a):

Odpowiem na tyle ile wiem, przydalby sie tutaj @somekind czy @katelx

tlumaczac na polski o co chodzi w zdaniu
direct array access via square-brackets and the field specifier dot. Note that, in .NET, arrays are a special and unique primitive of the Common Type System. As @Ani mentions above, this syntax cannot be used to change an individual field of a reference instance, such as a list, even when it is parameterized with a value-type

Bezposredni dostep do tablicy za pomoca [] oraz pola za pomoca kropki. Zwroc uwage na to ze w .NET tablice sa specjalnym i unikalnym prymitywem z podstawowym typow w System. Jak Ani wspomnial powyzej, ten kod nie moze byc uzyty by zmienic pojedyncze pole jako referencje obiektu, jak na przyklad lista, nawet gdy jest to okreslony typ jako value

W C# mamy reference oraz value, value zawsze sa kopiowane a reference zawsze przekazywane bezposrednio. Na dobra sprawe to co robi, to C# juz to robi (jako ze obiekt jest typem referencyjnym oraz tablica takze). Musialbym sprawdzic jak to dziala na kompilatorze, ale wydaje mi sie ze do funkcji bedzie przekazana referencja obiektu, wiec nie ma sensu tam robic ref

Chodzi o coś takiego?

public struct Foo {
  public List< int > lstInt;
  public int value;
  public Foo( int list_capacity ) { this.value = 0; this.lstInt = new List<int>(list_capacity); }
}

static void SomeFunc() {
  Foo foo1(16);
  Foo foo2 = foo1;
}

I mimo, że Foo jest value-type to zarówno foo1 jak i foo2 nie będą miały własnych list tylko będą 'wspołdzieliły' jedną?

fasadin napisał(a):
  1. Nie ma nic w dokumentacji by zapewnial ze beda obok siebie. Wiec nie mozesz zalozyc ze beda obok siebie. Zapewne beda. Nie jestem pewien czy Ms udostepnil zrodla jezeli chodzi o System.Generics.Collection. Poszukaj na githubie i po prostu sprawdz ;)

Najprostsze rozwiązania są najlepsze. Czemu nie wpadłem na to, żeby po prostu poszukać kodu? Heh.

fasadin napisał(a):

Chociaz dlaczego potrzebujesz by byly obok siebie? Mozna wiedziec co probujesz osiagnac?

Póki co nic konkretnego. Staram się zaprzyjaźnić z C#i poznać jego mechanizmy ;)

fasadin napisał(a):
  1. Z tego co pamietam to tak

Hmm... a takie coś?

public struct Foo : IComparable< Foo > { /* ... */ }
1

Struktury służą do definiowania typów reprezentujących jedną logiczną wartość (np. punkt w układzie współrzędnych, kolor w formacie RGB), mają rozmiar mniejszy niż 16 bajtów, są niezmienne i nie zachodzi ryzyko ich częstego boxowania.
Twoja struktura Foo łamie chyba wszystkie te zasady, więc powinna być klasą.

0

O tych zaleceniach czytałem. Tylko nie mogłem znaleźć skąd akurat te 16 bajtów? Czy to jest overhead jaki mają klasy?

Pytanie troszkę z innej beczki, ale wciąż dotyczące struktur. Mając przykładowo zdefiniowaną strukturę:

[StructLayout(LayoutKind.Explicit,Pack=1,Size=32)]
public struct DbfFieldInfo
{
  [FieldOffset(0)]
  public byte name;
  [FieldOffset(11)]
  public byte type;
  [FieldOffset(12)]
  public uint addr;
  [FieldOffset(16)]
  public byte lengthTotal;
  [FieldOffset(17)]
  public byte lengthDecimal;
  [FieldOffset(18)]
  public byte reserved;
}

Jest to struktura opisująca kolumne w formacie DBF(III). W jaki sposób stworzyć stringa, który zostanie zainicjalizowany bajtami z pola name? Czy coś takiego da się zrobić bez korzystanie z unsafe?

E: W kwestii formalnej - odkryłem atrybut MarshalAs ;)

[StructLayout(LayoutKind.Sequential,Pack=1)]
public struct DbfFieldInfo {
  [MarshalAs(UnmanagedType.ByValArray,SizeConst=11)]
  public byte name[];
  public byte type;
  public uint addr;
  public byte lengthTotal;
  public byte lengthDecimal;
  [MarshalAs(UnmanagedType.ByValArray,SizeConst=14)]
  public byte reserved[];
}

I ponoć to działa (tak pisali). A z tego co widzę to do c-stringów jest więcej opcji https://msdn.microsoft.com/pl-pl/library/system.runtime.interopservices.unmanagedtype(v=vs.110).aspx

1 użytkowników online, w tym zalogowanych: 0, gości: 1