1 / 10

Union in C#

Union in C#. 劉崇汎 崑山科技大學 電腦與通訊系 http://www.ksu.edu.tw. 前言. 在一般市面上的工具書中,都沒有介紹到如何在 C# 程式中使用 Union 。 缺乏 Union 將使得在很多應用 ( 如 Driver 的撰寫 ) 無法有效地做資料轉換。. 使用 Union 的步驟. 新增一個 C# 類別 專案選單,選擇新增類別 引用 System.Runtime.InteropServices; 在新類別程式碼最前方, using System.Runtime.InteropServices; 宣告要用 StructLayout

malott
Télécharger la présentation

Union in C#

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Union in C# 劉崇汎 崑山科技大學 電腦與通訊系 http://www.ksu.edu.tw

  2. 前言 • 在一般市面上的工具書中,都沒有介紹到如何在C#程式中使用Union。 • 缺乏Union將使得在很多應用(如Driver的撰寫)無法有效地做資料轉換。

  3. 使用Union的步驟 • 新增一個C#類別 • 專案選單,選擇新增類別 • 引用 System.Runtime.InteropServices; • 在新類別程式碼最前方,using System.Runtime.InteropServices; • 宣告要用StructLayout • 就是在類別的class宣告前加入一行[StructLayout(LayoutKind.Explicit)] • 用[FieldOffset(n)]指定每一個變數的位置。 • 也就是在每一個變數前加入一行[FieldOffset(n)] • 其中n就是以byte為單位的偏移值。第一個起始位置是 0。

  4. 程式碼 [FieldOffset(2)] public byte byte3; [FieldOffset(3)] public byte byte4; [FieldOffset(0)] public int myInt0; [FieldOffset(2)] public int myInt2; } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace UnionTest { [StructLayout(LayoutKind.Explicit)] public class MyUnionClass { [FieldOffset(0)] public byte byte1; [FieldOffset(1)] public byte byte2;

  5. 測試程式

  6. MyUnionTest class

  7. Form程式碼 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace UnionTest { public partial class Form1 : Form { MyUnionClass myUnion = new MyUnionClass(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { myUnion.byte1 = System.Convert.ToByte(textBox1.Text); textBox5.Text = myUnion.myInt0.ToString(); textBox6.Text = myUnion.myInt2.ToString(); } private void button2_Click(object sender, EventArgs e) { myUnion.byte2 = System.Convert.ToByte(textBox2.Text); textBox5.Text = myUnion.myInt0.ToString(); textBox6.Text = myUnion.myInt2.ToString(); }

  8. Form程式碼 private void button3_Click(object sender, EventArgs e) { myUnion.byte3 = System.Convert.ToByte(textBox3.Text); textBox5.Text = myUnion.myInt0.ToString(); textBox6.Text = myUnion.myInt2.ToString(); } private void button4_Click(object sender, EventArgs e) { myUnion.byte4 = System.Convert.ToByte(textBox4.Text); textBox5.Text = myUnion.myInt0.ToString(); textBox6.Text = myUnion.myInt2.ToString(); } private void button5_Click(object sender, EventArgs e) { myUnion.myInt0 = System.Convert.ToInt32(textBox5.Text); textBox1.Text = myUnion.byte1.ToString(); textBox2.Text = myUnion.byte2.ToString(); textBox3.Text = myUnion.byte3.ToString(); textBox4.Text = myUnion.byte4.ToString(); textBox6.Text = myUnion.myInt2.ToString(); } private void button6_Click(object sender, EventArgs e) { myUnion.myInt2 = System.Convert.ToInt32(textBox6.Text); textBox1.Text = myUnion.byte1.ToString(); textBox2.Text = myUnion.byte2.ToString(); textBox3.Text = myUnion.byte3.ToString(); textBox4.Text = myUnion.byte4.ToString(); textBox5.Text = myUnion.myInt0.ToString(); } } }

  9. 注意事項 • 注意Offset的值,出錯會很嚴重。 • Int現在都是32bits • 沒有比byte小的方式,需要用的時候請用mask去做and/ or 動作解決。 • 用物件導向寫法的 {set; get;}很簡潔好用。 (下頁) • 類似需要兩三個bit的欄位可以參考這個寫法。

  10. Bit Level的Union [FieldOffset(0)] private byte bit01; public byte Bit01 { set { if (value == 1) bit01 = (byte)(bit01 | 0x01); if (value == 0) bit01 = (byte)(bit01 & 0xFE); } get { return (byte)(bit01 & 0x01); } } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace UnionTest { [StructLayout(LayoutKind.Explicit)] public class MyUnionClass { [FieldOffset(0)] public byte byte1; [FieldOffset(1)] public byte byte2; …………………………. …………………….

More Related