odpopwiednik rekordów z delphi w c#

0

Witam,
Wiem że może idę na łatwiznę ale głównie zależy mi na czasie i dlatego o to pytam. Piszę malutką aplikację na Windows Phone w C# wykorzystującą sockety, serwer mam napisany w delphi i przyjmuje on pakiety w postaci rekordów o określonej długości np

type
  TPaczka = record
    Wartosc1: String[50];
    Wartosc2: String[100];
    Wartosc3: String[250];
  end;

W jaki sposób w C# zadeklarować coś takiego? Dla nie znających delphi (dużej większości) jest to rekord (odpowiednik chyba struktury w C# ?) o ustalonym rozmiarze stringów. Dodam że C# się usilnie uczę i dlatego nie wiem jak do tego podejść a w necie nic konkretnego nie znalazłem

1

Na przyklad tak:

struct Paczka
    {
        public Paczka()
        {
            Wartosc1 = new string[2];
            Wartosc2 = new string[20];
        }
        public string[] Wartosc1 { get; set; }
        public string[] Wartosc2 { get; set; }
    }
0

Dla struct w C# można stosować stały rozmiar tablicy, ale dotyczy to typów wartościowych.
Rozwiązaniem Twojego problemu może być wystawienie property o typie

string[]

, które będzie przykrywało prywatne pole w klasie + walidacja długości na set

.
0
FakeAccount napisał(a):

Na przyklad tak:

struct Paczka
    {
      **** public Paczka()****
        {
            Wartosc1 = new string[2];
            Wartosc2 = new string[20];
        }
        public string[] Wartosc1 { get; set; }
        public string[] Wartosc2 { get; set; }
    }

w pogrubionej linni wywala mi Structs cannot contain explicit parameterless constructors o co może chodzić?

0

Chodzi o to, co jest napisane, w C# struktury nie mogą mieć publicznego bezparametrowego konstruktora. W ogóle użycie struktury w tym przypadku to pomysł pozbawiony sensu.

Nie używaj struktur tylko klas, czyli napisz class zamiast struct.

0

Zacząłem dalej rozkminiać to deklaracja string[20] nie jest deklaracja tablicy 20tu stringów?

0

A właśnie nie o to mi chodziło, w delphi string[20] oznacza jednego stringa (nie tablice) o rozmiarze 20 znaków, a record oznacza taką paczkę ze stringami o różny określonych rozmiarach i szukam takiego odpowiednika C#

0

Zobacz sobie na to:
Tablice

0

Więc 20 znaków będziesz miał tak: char[20]
A co do rekrodu, nie ma czegoś takiego. Użyj klasy.

0

Nie wiem do czego Ci to potrzebne ale można by zrobić walidację, obsłużyć w właściwościach albo dodać nawet zwykłego ifa do sprawdzania... i na kilka innych sposobów w zależności do czego jest Ci to potrzebne. Ale jak bym miał zrobić to na chama to wyglądało by to następująco:

using System;
using System.Text;

public class Foo
{
   public Foo()
   {
      Bar = new StringBuilder(10, 10); // Maksymalnie 10 znaków
   }
   public StringBuilder Bar { get; set; }
}

public class Test
{
   public static void Main()
   {
      Foo foo = new Foo();
      foo.Bar.Append("12345");
      //foo.Bar.Append("123456"); // Tutaj rzuci wyjątkiem: System.ArgumentOutOfRangeException
      Console.WriteLine(foo.Bar);
   }
}
0

Ogólnie to problem bedzie z tym typem string - bo w zalezności od wersji delphi i od parametrów kompilacji mogą różnie wyglądać - w starym delphi np bedą miały na pierwszym bajcie długość stringu. Dlatego uzywanie takich rekordów nawet w delphi nie jest wskazane do wymiany informacji.

0
jagro napisał(a):

A właśnie nie o to mi chodziło, w delphi string[20] oznacza jednego stringa (nie tablice) o rozmiarze 20 znaków

Czyli string[20] w Delphi to tablica 20 znaków. I to jest w porządku, bo generalnie stringi to łańcuchy, czyli tablice znaków. Odpowiednikiem w C# jest string, który może mieć niemalże dowolną liczbę znaków, albo char[20], który ma zawsze 20 znaków. Ale łatwiej operuje się na typie string.

record oznacza taką paczkę ze stringami o różny określonych rozmiarach i szukam takiego odpowiednika C#

Odpowiednikiem recordu z Delphi w C# jest klasa. Tylko i wyłącznie.

0

mijacie się z problemem Panowie - pytanie jest co i jak zadeklarować aby odebrać z gniazda rekord wysłany z delphi.

type
  TPaczka = record
    Wartosc1: String[50];
    Wartosc2: String[100];
    Wartosc3: String[250];
  end;

public struct Paczka
{
public char[50] Wartosc1;
public char[100] Wartosc2;
public char[250] Wartosc3;
}

0
abrakadaber napisał(a):

mijacie się z problemem Panowie - pytanie jest co i jak zadeklarować aby odebrać z gniazda rekord wysłany z delphi.

type
  TPaczka = record
    Wartosc1: String[50];
    Wartosc2: String[100];
    Wartosc3: String[250];
  end;

record jest niespakowany - więc moga być pewne przesunięcia związane z wyrównaniem zmiennych, dodatkowo nadmiarowe informacje o wielkości stringa będziesz mieć.

public struct Paczka
{
public char[50] Wartosc1;
public char[100] Wartosc2;
public char[250] Wartosc3;
}



Jeśli nic sie nie zmieniło od kiedy miałem większą styczność z C# to beda 2 problemy
1) paczka może zostać wyrównana
2) wielkość bedzie inna niż twojego rekordu bo wielkość string[50] w delphi jest wieksza niż char[50] o nadmiarowe informacje o wielkości.
3) struct od class w C# różnił się głównie tym, że struct domyślnie przekazywany jest do funkcji przez wartośc, class za pomocą referencji.
0

Via MSDN: https://msdn.microsoft.com/en-gb/library/zycewsya(v=vs.80).aspx

public struct MyArray // This code must appear in an unsafe block
{
    public fixed char pathName[128];
}

Stałą długość tablicy można podać tylko w bloku unsafe, poza tym przypadkiem zawsze typ to po prostu

char[]

.

Lepszym (IMHO) rozwiązaniem jest:

private char[] _wartosc;
public char[] Wartosc 
{
	get { return _wartosc; }
	set 
	{
		ValidateAndSet(value);		
	} 
}
0

Widzę że jednak muszę wrócić do tego nad czym też już myślałem i zrobić to na tablicach z charem co wiąże się z ręcznym sklejanie kilku zmiennych w jedną paczkę. A odpowiednika rekordu szukałem ze względu na czytelność, a przede wszystkim łatwiejsze obrobienie (np wysłanie paczki z kilkoma zmiennymi bez szczególnej gimnastyki, obrobienie, skompresowanie, zaszyfrowanie itp). Samo wysłanie w delphi wygląda to mniej więcej tak jak poniżej i do tego dążyłem w C#

type
  TPaczka = record
    Wartosc1: String[50];
    Wartosc2: String[100];
    Wartosc3: String[250];
  end;

var P: TPaczka;

begin
P.Wartosc1:= 'aaaaa';
P.Wartosc2:= 'bbbbbbbb';
P.Wartosc3:= 'cccccccccccc';

send(Gniazdo, P, SizeOf(P), 0);
end;

A co do problemów o których pisał kaczus to tak po dłuższym rozkminieniu tak czy tak chyba skończyłoby się na tablicy char a raczej byte z odpowiednim przystosowaniem od strony C#, bo w delphi rekord z kilku zmiennych po rozłożeniu na bajty ma miej więcej postać:
[bajt określający długość zmiennej], [pierwszy bajt zmiennej] ..... [ostatni bajt zmiennej], [wypełnienie do określonej długości], [baj określający długość drugiej zmiennej], [pierwszy bajt drugiej zmiennej] ...

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