C# Language
संघ प्रकार बनाने के लिए C # संरचना का उपयोग कैसे करें (C यूनियनों के समान)
खोज…
टिप्पणियों
संघ प्रकार कई भाषाओं में उपयोग किए जाते हैं, विशेष रूप से सी-भाषा, कई अलग-अलग प्रकारों को समाहित करने के लिए जो एक ही मेमोरी स्पेस में "ओवरलैप" कर सकते हैं। दूसरे शब्दों में, उनमें अलग-अलग क्षेत्र हो सकते हैं, जिनमें से सभी एक ही मेमोरी ऑफ़सेट पर शुरू होते हैं, तब भी जब उनके पास अलग-अलग लंबाई और प्रकार हो सकते हैं। इससे मेमोरी को बचाने, और स्वचालित रूपांतरण करने दोनों का लाभ मिलता है।
कृपया, संरचना के निर्माता में टिप्पणियों पर ध्यान दें। जिस क्रम में खेतों को आरंभीकृत किया जाता है वह अत्यंत महत्वपूर्ण है। आप पहले सभी अन्य फ़ील्ड्स को इनिशियलाइज़ करना चाहते हैं और फिर उस मान को सेट करते हैं जिसे आप अंतिम स्टेटमेंट के रूप में बदलना चाहते हैं। क्योंकि फ़ील्ड ओवरलैप होते हैं, अंतिम मान सेटअप वह होता है जो मायने रखता है।
C # में C- स्टाइल यूनियन
यूनियन प्रकार कई भाषाओं में उपयोग किए जाते हैं, जैसे सी-भाषा, जिसमें कई अलग-अलग प्रकार होते हैं जो "ओवरलैप" कर सकते हैं। दूसरे शब्दों में, उनमें अलग-अलग क्षेत्र हो सकते हैं, जिनमें से सभी एक ही मेमोरी ऑफ़सेट पर शुरू होते हैं, तब भी जब उनके पास अलग-अलग लंबाई और प्रकार हो सकते हैं। इससे मेमोरी को बचाने, और स्वचालित रूपांतरण करने दोनों का लाभ मिलता है। एक उदाहरण के रूप में, एक आईपी पते के बारे में सोचो। आंतरिक रूप से, एक आईपी पते को पूर्णांक के रूप में दर्शाया जाता है, लेकिन कभी-कभी हम अलग-अलग बाइट घटक का उपयोग करना चाहते हैं, जैसे कि बाइट 1 में। Btete2.Byte3.Byte4। यह किसी भी प्रकार के मान के लिए काम करता है, जैसे कि यह Int32 या लंबे समय तक, या अन्य संरचनाओं के लिए आदिम है, जिन्हें आप स्वयं परिभाषित करते हैं।
हम स्पष्ट लेआउट संरचनाओं का उपयोग करके C # में समान प्रभाव प्राप्त कर सकते हैं।
using System;
using System.Runtime.InteropServices;
// The struct needs to be annotated as "Explicit Layout"
[StructLayout(LayoutKind.Explicit)]
struct IpAddress
{
// The "FieldOffset" means that this Integer starts, an offset in bytes.
// sizeof(int) 4, sizeof(byte) = 1
[FieldOffset(0)] public int Address;
[FieldOffset(0)] public byte Byte1;
[FieldOffset(1)] public byte Byte2;
[FieldOffset(2)] public byte Byte3;
[FieldOffset(3)] public byte Byte4;
public IpAddress(int address) : this()
{
// When we init the Int, the Bytes will change too.
Address = address;
}
// Now we can use the explicit layout to access the
// bytes separately, without doing any conversion.
public override string ToString() => $"{Byte1}.{Byte2}.{Byte3}.{Byte4}";
}
इस तरह से संरचना को परिभाषित करने के बाद, हम इसका उपयोग कर सकते हैं जैसा कि हम सी में एक यूनियन का उपयोग करेंगे। उदाहरण के लिए, आइए एक रैंडम इंटेगर के रूप में एक आईपी एड्रेस बनाएं और फिर पते में पहले टोकन को बदलकर '100' में बदल दें। 'ABCD' से '100.BCD' तक:
var ip = new IpAddress(new Random().Next());
Console.WriteLine($"{ip} = {ip.Address}");
ip.Byte1 = 100;
Console.WriteLine($"{ip} = {ip.Address}");
आउटपुट:
75.49.5.32 = 537211211
100.49.5.32 = 537211236
C # में यूनियन टाइप में स्ट्रक्चर फील्ड भी हो सकते हैं
आदिमों के अलावा, C # में स्पष्ट लेआउट संरचनाएं (यूनियन), अन्य संरचनाएं भी हो सकती हैं। जब तक कोई फ़ील्ड मान प्रकार और संदर्भ नहीं है, तब तक उसे एक संघ में शामिल किया जा सकता है:
using System;
using System.Runtime.InteropServices;
// The struct needs to be annotated as "Explicit Layout"
[StructLayout(LayoutKind.Explicit)]
struct IpAddress
{
// Same definition of IpAddress, from the example above
}
// Now let's see if we can fit a whole URL into a long
// Let's define a short enum to hold protocols
enum Protocol : short { Http, Https, Ftp, Sftp, Tcp }
// The Service struct will hold the Address, the Port and the Protocol
[StructLayout(LayoutKind.Explicit)]
struct Service
{
[FieldOffset(0)] public IpAddress Address;
[FieldOffset(4)] public ushort Port;
[FieldOffset(6)] public Protocol AppProtocol;
[FieldOffset(0)] public long Payload;
public Service(IpAddress address, ushort port, Protocol protocol)
{
Payload = 0;
Address = address;
Port = port;
AppProtocol = protocol;
}
public Service(long payload)
{
Address = new IpAddress(0);
Port = 80;
AppProtocol = Protocol.Http;
Payload = payload;
}
public Service Copy() => new Service(Payload);
public override string ToString() => $"{AppProtocol}//{Address}:{Port}/";
}
अब हम यह सत्यापित कर सकते हैं कि संपूर्ण सेवा संघ एक लंबी (8 बाइट्स) के आकार में फिट बैठता है।
var ip = new IpAddress(new Random().Next());
Console.WriteLine($"Size: {Marshal.SizeOf(ip)} bytes. Value: {ip.Address} = {ip}.");
var s1 = new Service(ip, 8080, Protocol.Https);
var s2 = new Service(s1.Payload);
s2.Address.Byte1 = 100;
s2.AppProtocol = Protocol.Ftp;
Console.WriteLine($"Size: {Marshal.SizeOf(s1)} bytes. Value: {s1.Address} = {s1}.");
Console.WriteLine($"Size: {Marshal.SizeOf(s2)} bytes. Value: {s2.Address} = {s2}.");