PDA

View Full Version : آموزش: typeCast در C#‎



golinazhad_h
جمعه 15 دی 1391, 17:01 عصر
سلام دوستان
من یک کلاس دارم که میخواهم آن را تبدیل کنم به آرایه ، برای این کار از Serialization استفاده میکنم ولی جواب نمیده
کلاس به صورت زیر تعریف شده:

[CODE]
[Serializable()]
public class Packet
{

public Int64 Item1;
public Int64 Item2;
public Int64 Item3;
public Int16 Item4;
public Byte[] BUFF = new Byte[1000];
}

[CODE/]

تابعی که برای تبدیل به ارایه استفاده شده بصورت زیر است:
[CODE]
private byte[] toarray(Packet pk)
{
BinaryFormatter fr = new BinaryFormatter();
MemoryStream st = new MemoryStream();
fr.Serialize(st, pk);
return st.ToArray();

}



[CODE/]
ولی آرایه برگشتی اون نیست که مد نظر من باشه

PhoenixNet
جمعه 15 دی 1391, 17:19 عصر
سلام
منظورتون از اینکه به آرایه تبدیل بشود چیه؟فرمت خروجیتون چیه؟با استفاده از http://json.codeplex.com/ میتوانید کلاس خود را سریالی کنید با فرمت json.

plus
جمعه 15 دی 1391, 17:27 عصر
شما چه ارایه ای مد نظرتون هست.من کد رو تست کردم به نظر میاد درست جواب میده:

Packet packet = new Packet();
packet.BUFF[50] = 123;
packet.BUFF[100] = 250;

BinaryFormatter binFormatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
binFormatter.Serialize(memStream, packet);
File.WriteAllBytes(@"d:\temp\test.txt", memStream.ToArray());
memStream.Close();

memStream = new MemoryStream(File.ReadAllBytes(@"d:\temp\test.txt"));
Packet newPacket = binFormatter.Deserialize(memStream) as Packet;
MessageBox.Show(string.Format("{0}, {1}", newPacket.BUFF[50], newPacket.BUFF[100]));
memStream.Close();

دو بایت توی آرایه Buffer نوشته میشه، بعد از Serialize، خروجی توی فایل نوشته میشه، بعد فایل خونده میشه و Deserialize میشه، آرایه Buffer مقدار درستی داره...

golinazhad_h
جمعه 15 دی 1391, 17:55 عصر
شما چه ارایه ای مد نظرتون هست.من کد رو تست کردم به نظر میاد درست جواب میده:

Packet packet = new Packet();
packet.BUFF[50] = 123;
packet.BUFF[100] = 250;

BinaryFormatter binFormatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
binFormatter.Serialize(memStream, packet);
File.WriteAllBytes(@"d:\temp\test.txt", memStream.ToArray());
memStream.Close();

memStream = new MemoryStream(File.ReadAllBytes(@"d:\temp\test.txt"));
Packet newPacket = binFormatter.Deserialize(memStream) as Packet;
MessageBox.Show(string.Format("{0}, {1}", newPacket.BUFF[50], newPacket.BUFF[100]));
memStream.Close();

دو بایت توی آرایه Buffer نوشته میشه، بعد از Serialize، خروجی توی فایل نوشته میشه، بعد فایل خونده میشه و Deserialize میشه، آرایه Buffer مقدار درستی داره...


این کلاس مثل یک ساختار داده است می خواهم همین ساختار را تبدیل به بایت کنم و از طریق سوکت ارسال کنم
من کلاس را مقدار دهی میکنم وقتی توسط تابع تبدیل میکنم به آرایه چند بایت آرایه را در خروجی نشان میدم میبینم درست نیست مثلا اگر Parm1 را مساوی 512 قرار بدهم باید Buff[1] مساوی 2 باشد دیگه ولی یه عدد دیگه نشون میده
و فیلدهایی هم که در کلاس صفر مقدار دهی شدند در Buff همش مساوی 255 هست

plus
جمعه 15 دی 1391, 18:10 عصر
شما وقتی با این روش یک شی رو Serialize میکنید، تا وقتی که خروجی رو Deserialize نکنید نمیتونید هیچ انتظاری از مقدار خروجی داشته باشید.شاید شما قصدتون، نوشتن یک شی در آرایه به روش ++C/C هست (بدون Serialization به صورتی که بایت به بایت نوشته بشه) ؟
در ضمن منظورتون رو Param1 میتوجه نشدم.

golinazhad_h
جمعه 15 دی 1391, 18:28 عصر
شما وقتی با این روش یک شی رو Serialize میکنید، تا وقتی که خروجی رو Deserialize نکنید نمیتونید هیچ انتظاری از مقدار خروجی داشته باشید.شاید شما قصدتون، نوشتن یک شی در آرایه به روش ++C/C هست (بدون Serialization به صورتی که بایت به بایت نوشته بشه) ؟
در ضمن منظورتون رو Param1 میتوجه نشدم.

آره دقیقا
یعنی میخوام کلاسی را که ساختم و نوع داده همه فیلدهاش استانداره یعنی int ,Byte میخواهم پشت سرهم بریزم داخل یک بافر یعنی نوعی Typecast
منظور از Parm1 همون اولین فیلد تعریف شده در کلاس بوده مهندس

plus
جمعه 15 دی 1391, 18:52 عصر
راه ساده برای این کار اینه که تک تک فیلد های کلاس رو با استفاده از BinaryWriter بنویسید و بعد با استفاده از BinaryReader بخونید:

private void Form1_Load(object sender, EventArgs e)
{
Packet packet = new Packet();
packet.BUFF[0] = 100;
packet.Item1 = 123;
byte[] output = packet.ToByteArray();
//
//
Packet newPacket = Packet.FromByteArray(output);
}

public class Packet
{

public Int64 Item1;
public Int64 Item2;
public Int64 Item3;
public Int16 Item4;
public Byte[] BUFF = new Byte[1000];

public byte[] ToByteArray()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(Item1);
bw.Write(Item2);
bw.Write(Item3);
bw.Write(Item4);
bw.Write(BUFF);
bw.Close();

byte[] output = ms.ToArray();
ms.Close();
return output;
}

public static Packet FromByteArray(byte[] input)
{
MemoryStream ms = new MemoryStream(input);
BinaryReader br = new BinaryReader(ms);
Packet packet = new Packet();

packet.Item1 = br.ReadInt64();
packet.Item2 = br.ReadInt64();
packet.Item3 = br.ReadInt64();
packet.Item4 = br.ReadInt16();
packet.BUFF = br.ReadBytes(packet.BUFF.Length);

return packet;
}
}

golinazhad_h
جمعه 15 دی 1391, 19:15 عصر
مرسی مهندس دستت درد نکنه خودم این کارو انجام دادم میخواستم ببینم متد آماده ای یا روش بهتری داره که خودم کد ننویسم
باز تشکر که وقت گذاشتی جواب دادی

plus
جمعه 15 دی 1391, 19:20 عصر
روش دیگه ش استفاده استفاده از Marshal هست، که البته باید اونوقت از Struct بجای کلاس استفاده بشه....