c# - मैं एन्कोडिंग मैन्युअल रूप से निर्दिष्ट किए बिना सी#में तारों का लगातार बाइट प्रतिनिधित्व कैसे प्राप्त करूं?




.net string (25)

मैन्युअल रूप से एक विशिष्ट एन्कोडिंग निर्दिष्ट किए बिना मैं string को एक byte[] में .NET (C #) में कैसे परिवर्तित करूं?

मैं स्ट्रिंग एन्क्रिप्ट करने जा रहा हूँ। मैं इसे परिवर्तित किए बिना एन्क्रिप्ट कर सकता हूं, लेकिन मैं अभी भी जानना चाहता हूं कि यहां एन्कोडिंग क्यों खेलती है।

इसके अलावा, एन्कोडिंग को क्यों ध्यान में रखा जाना चाहिए? क्या मैं बस स्ट्रिंग को संग्रहीत करने वाले बाइट्स को नहीं प्राप्त कर सकता हूं? चरित्र एन्कोडिंग पर निर्भरता क्यों है?


Answers

With the advent of Span<T> released with C# 7.2, the canonical technique to capture the underlying memory representation of a string into a managed byte array is:

byte[] bytes = "rubbish_\u9999_string".AsSpan().AsBytes().ToArray();

Converting it back should be a non-starter because that means you are in fact interpreting the data somehow, but for the sake of completeness:

string s;
unsafe
{
    fixed (char* f = &bytes.AsSpan().NonPortableCast<byte, char>().DangerousGetPinnableReference())
    {
        s = new string(f);
    }
}

The names NonPortableCast and DangerousGetPinnableReference should further the argument that you probably shouldn't be doing this.

Note that working with Span<T> requires installing the System.Memory NuGet package .

Regardless, the actual original question and follow-up comments imply that the underlying memory is not being "interpreted" (which I assume means is not modified or read beyond the need to write it as-is), indicating that some implementation of the Stream class should be used instead of reasoning about the data as strings at all.


इसे आज़माएं, बहुत कम कोड:

System.Text.Encoding.UTF8.GetBytes("TEST String");

खैर, मैंने सभी उत्तरों को पढ़ लिया है और वे एन्कोडिंग या सीरियलाइजेशन के बारे में एक थे जो अनपेक्षित सरोगेट छोड़ देता है।

यह खराब है जब स्ट्रिंग, उदाहरण के लिए, SQL सर्वर से आता है जहां इसे एक बाइट सरणी संग्रह से बनाया गया था, उदाहरण के लिए, एक पासवर्ड हैश। अगर हम इससे कुछ भी छोड़ देते हैं, तो यह एक अवैध हैश स्टोर करेगा, और अगर हम इसे एक्सएमएल में स्टोर करना चाहते हैं, तो हम इसे बरकरार रखना चाहते हैं (क्योंकि एक्सएमएल लेखक किसी भी अप्रयुक्त सरोगेट पर अपवाद छोड़ देता है)।

तो मैं ऐसे मामलों में बाइट एरे के Base64 एन्कोडिंग का उपयोग करता हूं, लेकिन हे, इंटरनेट पर सी # में इसका एक ही समाधान है, और इसमें इसमें बग है और यह केवल एक ही तरीका है, इसलिए मैंने बग तय कर लिया है और वापस लिखा है प्रक्रिया। यहां आप भविष्य के googlers हैं:

public static byte[] StringToBytes(string str)
{
    byte[] data = new byte[str.Length * 2];
    for (int i = 0; i < str.Length; ++i)
    {
        char ch = str[i];
        data[i * 2] = (byte)(ch & 0xFF);
        data[i * 2 + 1] = (byte)((ch & 0xFF00) >> 8);
    }

    return data;
}

public static string StringFromBytes(byte[] arr)
{
    char[] ch = new char[arr.Length / 2];
    for (int i = 0; i < ch.Length; ++i)
    {
        ch[i] = (char)((int)arr[i * 2] + (((int)arr[i * 2 + 1]) << 8));
    }
    return new String(ch);
}

यह एक लोकप्रिय सवाल है। यह समझना महत्वपूर्ण है कि प्रश्न लेखक क्या पूछ रहा है, और यह कि सबसे सामान्य आवश्यकता की तुलना में अलग है। उस कोड के दुरुपयोग को हतोत्साहित करने के लिए जहां इसकी आवश्यकता नहीं है, मैंने बाद में उत्तर दिया है।

सामान्य आवश्यकता

प्रत्येक स्ट्रिंग में एक चरित्र सेट और एन्कोडिंग होता है। जब आप System.String ऑब्जेक्ट को System.Byte सरणी में कनवर्ट करते हैं। System.Byte आपके पास अभी भी एक वर्ण सेट और एन्कोडिंग है। अधिकांश उपयोगों के लिए, आपको पता चलेगा कि आपको कौन सा चरित्र सेट और एन्कोडिंग चाहिए और .NET "रूपांतरण के साथ प्रतिलिपि" बनाना आसान बनाता है। बस उचित Encoding कक्षा का चयन करें।

// using System.Text;
Encoding.UTF8.GetBytes(".NET String to byte array")

रूपांतरण को उन मामलों को संभालने की आवश्यकता हो सकती है जहां लक्षित वर्ण सेट या एन्कोडिंग स्रोत में मौजूद किसी वर्ण का समर्थन नहीं करती है। आपके पास कुछ विकल्प हैं: अपवाद, प्रतिस्थापन या छोड़ना। डिफ़ॉल्ट नीति '?' को प्रतिस्थापित करना है।

// using System.Text;
var text = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes("You win €100")); 
                                                      // -> "You win ?100"

जाहिर है, रूपांतरण जरूरी नहीं हैं!

नोट: System.String लिए। स्रोत चरित्र सेट System.String यूनिकोड है।

एकमात्र भ्रमित बात यह है कि .NET उस चरित्र सेट के एक विशेष एन्कोडिंग के नाम के लिए वर्ण सेट के नाम का उपयोग करता है। Encoding.UnicodeEncoding.UTF16 को Encoding.UTF16 कहा जाना चाहिए।

यह ज्यादातर उपयोग के लिए है। यदि आपको यही चाहिए, तो यहां पढ़ना बंद करें। यदि आप समझ नहीं पाते कि एन्कोडिंग क्या है, तो joelonsoftware.com/articles/Unicode.html मजेदार देखें।

विशिष्ट आवश्यकता

अब, प्रश्न लेखक पूछता है, "प्रत्येक स्ट्रिंग बाइट्स की सरणी के रूप में संग्रहीत होती है, है ना? मुझे बस उन बाइट्स क्यों नहीं मिल सकते हैं?"

वह कोई रूपांतरण नहीं चाहता है।

सी # spec से :

सी # में कैरेक्टर और स्ट्रिंग प्रसंस्करण यूनिकोड एन्कोडिंग का उपयोग करता है। चार प्रकार एक यूटीएफ -16 कोड इकाई का प्रतिनिधित्व करता है, और स्ट्रिंग प्रकार यूटीएफ -16 कोड इकाइयों के अनुक्रम का प्रतिनिधित्व करता है।

इसलिए, हम जानते हैं कि अगर हम शून्य रूपांतरण (यानी, यूटीएफ -16 से यूटीएफ -16 तक) मांगते हैं, तो हमें वांछित परिणाम मिलेंगे:

Encoding.Unicode.GetBytes(".NET String to byte array")

लेकिन एन्कोडिंग के उल्लेख से बचने के लिए, हमें इसे एक और तरीके से करना होगा। यदि एक मध्यवर्ती डेटा प्रकार स्वीकार्य है, तो इसके लिए एक वैचारिक शॉर्टकट है:

".NET String to byte array".ToCharArray()

यह हमें वांछित डेटाटाइप नहीं प्राप्त करता है लेकिन मेहरदाद का जवाब दिखाता है कि इस चार सरणी को BlockCopy का उपयोग करके बाइट सरणी में कैसे परिवर्तित किया जाए। हालांकि, यह दो बार स्ट्रिंग की प्रतिलिपि बनाता है! और, यह भी स्पष्ट रूप से एन्कोडिंग-विशिष्ट कोड का उपयोग करता है: डेटाटाइप System.CharSystem.Char

एक बाइनर का उपयोग करने के लिए स्ट्रिंग को संग्रहीत वास्तविक बाइट्स को प्राप्त करने का एकमात्र तरीका है। fixed कथन मूल्यों का पता लेने की अनुमति देता है। सी # spec से:

[के लिए] प्रकार स्ट्रिंग की अभिव्यक्ति, ... प्रारंभकर्ता स्ट्रिंग में पहले वर्ण के पते की गणना करता है।

ऐसा करने के लिए, कंपाइलर स्ट्रिंग ऑब्जेक्ट के अन्य हिस्सों पर RuntimeHelpers.OffsetToStringData साथ कोड छोड़ RuntimeHelpers.OffsetToStringData । इसलिए, कच्चे बाइट प्राप्त करने के लिए, बस स्ट्रिंग में एक पॉइंटर बनाएं और आवश्यक बाइट्स की संख्या कॉपी करें।

// using System.Runtime.InteropServices
unsafe byte[] GetRawBytes(String s)
{
    if (s == null) return null;
    var codeunitCount = s.Length;
    /* We know that String is a sequence of UTF-16 codeunits 
       and such codeunits are 2 bytes */
    var byteCount = codeunitCount * 2; 
    var bytes = new byte[byteCount];
    fixed(void* pRaw = s)
    {
        Marshal.Copy((IntPtr)pRaw, bytes, 0, byteCount);
    }
    return bytes;
}

जैसा कि @CodesInChaos ने बताया, परिणाम मशीन की अंतहीनता पर निर्भर करता है। लेकिन सवाल लेखक उस से चिंतित नहीं है।


BinaryFormatter bf = new BinaryFormatter();
byte[] bytes;
MemoryStream ms = new MemoryStream();

string orig = "喂 Hello 谢谢 Thank You";
bf.Serialize(ms, orig);
ms.Seek(0, 0);
bytes = ms.ToArray();

MessageBox.Show("Original bytes Length: " + bytes.Length.ToString());

MessageBox.Show("Original string Length: " + orig.Length.ToString());

for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo encrypt
for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo decrypt

BinaryFormatter bfx = new BinaryFormatter();
MemoryStream msx = new MemoryStream();            
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
string sx = (string)bfx.Deserialize(msx);

MessageBox.Show("Still intact :" + sx);

MessageBox.Show("Deserialize string Length(still intact): " 
    + sx.Length.ToString());

BinaryFormatter bfy = new BinaryFormatter();
MemoryStream msy = new MemoryStream();
bfy.Serialize(msy, sx);
msy.Seek(0, 0);
byte[] bytesy = msy.ToArray();

MessageBox.Show("Deserialize bytes Length(still intact): " 
   + bytesy.Length.ToString());

Two ways:

public static byte[] StrToByteArray(this string s)
{
    List<byte> value = new List<byte>();
    foreach (char c in s.ToCharArray())
        value.Add(c.ToByte());
    return value.ToArray();
}

And,

public static byte[] StrToByteArray(this string s)
{
    s = s.Replace(" ", string.Empty);
    byte[] buffer = new byte[s.Length / 2];
    for (int i = 0; i < s.Length; i += 2)
        buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
    return buffer;
}

I tend to use the bottom one more often than the top, haven't benchmarked them for speed.


byte[] strToByteArray(string str)
{
    System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    return enc.GetBytes(str);
}

स्वीकृत उत्तर बहुत जटिल है। इसके लिए शामिल .NET कक्षाओं का उपयोग करें:

const string data = "A string with international characters: Norwegian: ÆØÅæøå, Chinese: 喂 谢谢";
var bytes = System.Text.Encoding.UTF8.GetBytes(data);
var decoded = System.Text.Encoding.UTF8.GetString(bytes);

यदि आपको नहीं करना है तो पहिया को फिर से न करें ...


The string can be converted to byte array in few different ways, due to the following fact: .NET supports Unicode, and Unicode standardizes several difference encodings called UTFs. They have different lengths of byte representation but are equivalent in that sense that when a string is encoded, it can be coded back to the string, but if the string is encoded with one UTF and decoded in the assumption of different UTF if can be screwed up.

Also, .NET supports non-Unicode encodings, but they are not valid in general case (will be valid only if a limited sub-set of Unicode code point is used in an actual string, such as ASCII). Internally, .NET supports UTF-16, but for stream representation, UTF-8 is usually used. It is also a standard-de-facto for Internet.

Not surprisingly, serialization of string into an array of byte and deserialization is supported by the class System.Text.Encoding , which is an abstract class; its derived classes support concrete encodings: ASCIIEncoding and four UTFs ( System.Text.UnicodeEncoding supports UTF-16)

Ref this link.

For serialization to an array of bytes using System.Text.Encoding.GetBytes . For the inverse operation use System.Text.Encoding.GetChars . This function returns an array of characters, so to get a string, use a string constructor System.String(char[]) .
Ref this page.

उदाहरण:

string myString = //... some string

System.Text.Encoding encoding = System.Text.Encoding.UTF8; //or some other, but prefer some UTF is Unicode is used
byte[] bytes = encoding.GetBytes(myString);

//next lines are written in response to a follow-up questions:

myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);
myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);

//how many times shall I repeat it to show there is a round-trip? :-)

You can use the following code for conversion between string and byte array.

string s = "Hello World";

// String to Byte[]

byte[] byte1 = System.Text.Encoding.Default.GetBytes(s);

// OR

byte[] byte2 = System.Text.ASCIIEncoding.Default.GetBytes(s);

// Byte[] to string

string str = System.Text.Encoding.UTF8.GetString(byte1);

simple code with LINQ

string s = "abc"
byte[] b = s.Select(e => (byte)e).ToArray();

EDIT : as commented below, it is not a good way.

but you can still use it to understand LINQ with a more appropriate coding :

string s = "abc"
byte[] b = s.Cast<byte>().ToArray();

उपयोग:

    string text = "string";
    byte[] array = System.Text.Encoding.UTF8.GetBytes(text);

The result is:

[0] = 115
[1] = 116
[2] = 114
[3] = 105
[4] = 110
[5] = 103

If you really want a copy of the underlying bytes of a string, you can use a function like the one that follows. However, you shouldn't please read on to find out why.

[DllImport(
        "msvcrt.dll",
        EntryPoint = "memcpy",
        CallingConvention = CallingConvention.Cdecl,
        SetLastError = false)]
private static extern unsafe void* UnsafeMemoryCopy(
    void* destination,
    void* source,
    uint count);

public static byte[] GetUnderlyingBytes(string source)
{
    var length = source.Length * sizeof(char);
    var result = new byte[length];
    unsafe
    {
        fixed (char* firstSourceChar = source)
        fixed (byte* firstDestination = result)
        {
            var firstSource = (byte*)firstSourceChar;
            UnsafeMemoryCopy(
                firstDestination,
                firstSource,
                (uint)length);
        }
    }

    return result;
}

This function will get you a copy of the bytes underlying your string, pretty quickly. You'll get those bytes in whatever way they are encoding on your system. This encoding is almost certainly UTF-16LE but that is an implementation detail you shouldn't have to care about.

It would be safer, simpler and more reliable to just call,

System.Text.Encoding.Unicode.GetBytes()

In all likelihood this will give the same result, is easier to type, and the bytes will always round-trip with a call to

System.Text.Encoding.Unicode.GetString()

एक string को byte सरणी में कनवर्ट करने के लिए सी #:

public static byte[] StrToByteArray(string str)
{
   System.Text.UTF8Encoding  encoding=new System.Text.UTF8Encoding();
   return encoding.GetBytes(str);
}

आपके प्रश्न का पहला भाग (बाइट्स कैसे प्राप्त करें) पहले से ही दूसरों द्वारा उत्तर दिया गया था: System.Text.Encoding नामस्थान में देखें।

मैं आपके अनुवर्ती प्रश्न को संबोधित करूंगा: आपको एन्कोडिंग चुनने की आवश्यकता क्यों है? आप स्ट्रिंग क्लास से खुद क्यों नहीं प्राप्त कर सकते हैं?

जवाब दो भागों में है।

सबसे पहले, स्ट्रिंग क्लास द्वारा आंतरिक रूप से उपयोग किए जाने वाले बाइट्स कोई फर्क नहीं पड़ता , और जब भी आप मानते हैं कि आप एक बग पेश कर रहे हैं।

यदि आपका प्रोग्राम पूरी तरह से नेट दुनिया के भीतर है तो आपको तारों के लिए बाइट सरणी प्राप्त करने की चिंता करने की आवश्यकता नहीं है, भले ही आप किसी नेटवर्क पर डेटा भेज रहे हों। इसके बजाय, डेटा संचारित करने के बारे में चिंता करने के लिए .NET Serialization का उपयोग करें। आप वास्तविक बाइट्स के बारे में और चिंता नहीं करते हैं: सीरियलाइजेशन फॉर्मेटर यह आपके लिए करता है।

दूसरी तरफ, यदि आप इन बाइट्स को कहीं भेज रहे हैं तो आप गारंटी नहीं दे सकते हैं। नेट सीरियलाइज्ड स्ट्रीम से डेटा खींचेंगे? इस मामले में आपको निश्चित रूप से एन्कोडिंग के बारे में चिंता करने की आवश्यकता है, क्योंकि जाहिर है कि यह बाहरी प्रणाली परवाह है। तो फिर, स्ट्रिंग द्वारा उपयोग किए जाने वाले आंतरिक बाइट्स कोई फर्क नहीं पड़ता: आपको एन्कोडिंग चुनने की आवश्यकता है ताकि आप प्राप्त करने वाले अंत में इस एन्कोडिंग के बारे में स्पष्ट हो सकें, भले ही यह आंतरिक रूप से .NET द्वारा उपयोग किया गया एक ही एन्कोडिंग हो।

मैं समझता हूं कि इस मामले में आप यथासंभव स्मृति में स्ट्रिंग वैरिएबल द्वारा संग्रहीत वास्तविक बाइट्स का उपयोग करना पसंद कर सकते हैं, इस विचार के साथ कि यह आपके बाइट स्ट्रीम को बनाने में कुछ काम बचा सकता है। हालांकि, मैंने इसे आपके पास रखा है यह सुनिश्चित करने के मुकाबले यह महत्वपूर्ण नहीं है कि आपका आउटपुट दूसरी छोर पर समझा जाए और यह गारंटी दे कि आपको अपने एन्कोडिंग के साथ स्पष्ट होना चाहिए। इसके अतिरिक्त, यदि आप वास्तव में अपने आंतरिक बाइट्स से मेल खाना चाहते हैं, तो आप पहले से ही Unicode एन्कोडिंग चुन सकते हैं, और उस प्रदर्शन बचत को प्राप्त कर सकते हैं।

जो मुझे दूसरे भाग में लाता है ... Unicode एन्कोडिंग चुनना नेटिंग बाइट्स का उपयोग करने के लिए नेट है। आपको इस एन्कोडिंग को चुनने की ज़रूरत है, क्योंकि जब कुछ नए-फेंगले यूनिकोड-प्लस बाहर आते हैं तो नेट रनटाइम को आपके प्रोग्राम को तोड़ने के बिना इस नए, बेहतर एन्कोडिंग मॉडल का उपयोग करने के लिए स्वतंत्र होना चाहिए। लेकिन, इस पल के लिए (और भविष्य में अचूक भविष्य), केवल यूनिकोड एन्कोडिंग चुनने से आप जो चाहते हैं उसे चुनते हैं।

यह समझना भी महत्वपूर्ण है कि आपकी स्ट्रिंग को तार पर फिर से लिखा जाना चाहिए, और जब आप एक मिलान एन्कोडिंग का उपयोग करते हैं तो इसमें बिट-पैटर्न का कम से कम कुछ अनुवाद शामिल होता है। कंप्यूटर को बिग बनाम लिटिल एंडियन, नेटवर्क बाइट ऑर्डर, पैकेटिज़ेशन, सत्र जानकारी इत्यादि जैसी चीजों के लिए जिम्मेदार होना चाहिए।


यह आपकी स्ट्रिंग के एन्कोडिंग पर निर्भर करता है ( ASCII , UTF-8 , ...)।

उदाहरण के लिए:

byte[] b1 = System.Text.Encoding.UTF8.GetBytes (myString);
byte[] b2 = System.Text.Encoding.ASCII.GetBytes (myString);

एन्कोडिंग मामलों का एक छोटा सा नमूना क्यों:

string pi = "\u03a0";
byte[] ascii = System.Text.Encoding.ASCII.GetBytes (pi);
byte[] utf8 = System.Text.Encoding.UTF8.GetBytes (pi);

Console.WriteLine (ascii.Length); //Will print 1
Console.WriteLine (utf8.Length); //Will print 2
Console.WriteLine (System.Text.Encoding.ASCII.GetString (ascii)); //Will print '?'

एएससीआईआईआई विशेष पात्रों से निपटने के लिए सुसज्जित नहीं है।

आंतरिक रूप से, .NET ढांचा स्ट्रिंग का प्रतिनिधित्व करने के लिए UTF-16 का उपयोग करता है, इसलिए यदि आप बस सटीक बाइट्स प्राप्त करना चाहते हैं जो .NET उपयोग करता है, तो System.Text.Encoding.Unicode.GetBytes (...) उपयोग करें।

अधिक जानकारी के लिए .NET Framework (MSDN) में वर्ण एन्कोडिंग देखें।


I'm not sure, but I think the string stores its info as an array of Chars, which is inefficient with bytes. Specifically, the definition of a Char is "Represents a Unicode character".

take this example sample:

String str = "asdf éß";
String str2 = "asdf gh";
EncodingInfo[] info =  Encoding.GetEncodings();
foreach (EncodingInfo enc in info)
{
    System.Console.WriteLine(enc.Name + " - " 
      + enc.GetEncoding().GetByteCount(str)
      + enc.GetEncoding().GetByteCount(str2));
}

Take note that the Unicode answer is 14 bytes in both instances, whereas the UTF-8 answer is only 9 bytes for the first, and only 7 for the second.

So if you just want the bytes used by the string, simply use Encoding.Unicode , but it will be inefficient with storage space.


Simply use this:

byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);

It depends on what you want the bytes FOR

This is because, as Tyler so aptly said , "Strings aren't pure data. They also have information ." In this case, the information is an encoding that was assumed when the string was created.

Assuming that you have binary data (rather than text) stored in a string

This is based off of OP's comment on his own question, and is the correct question if I understand OP's hints at the use-case.

Storing binary data in strings is probably the wrong approach because of the assumed encoding mentioned above! Whatever program or library stored that binary data in a string (instead of a byte[] array which would have been more appropriate) has already lost the battle before it has begun. If they are sending the bytes to you in a REST request/response or anything that must transmit strings, Base64 would be the right approach.

If you have a text string with an unknown encoding

Everybody else answered this incorrect question incorrectly.

If the string looks good as-is, just pick an encoding (preferably one starting with UTF), use the corresponding System.Text.Encoding.???.GetBytes() function, and tell whoever you give the bytes to which encoding you picked.


From byte[] to string :

        return BitConverter.ToString(bytes);

bytes[] buffer = UnicodeEncoding.UTF8.GetBytes(string something); //for converting to UTF then get its bytes

bytes[] buffer = ASCIIEncoding.ASCII.GetBytes(string something); //for converting to ascii then get its bytes

Fastest way

public static byte[] GetBytes(string text)
{
    return System.Text.ASCIIEncoding.UTF8.GetBytes(text);
}

EDIT as Makotosan commented this is now the best way:

Encoding.UTF8.GetBytes(text)

The key issue is that a glyph in a string takes 32 bits (16 bits for a character code) but a byte only has 8 bits to spare. A one-to-one mapping doesn't exist unless you restrict yourself to strings that only contain ASCII characters. System.Text.Encoding has lots of ways to map a string to byte[], you need to pick one that avoids loss of information and that is easy to use by your client when she needs to map the byte[] back to a string.

Utf8 is a popular encoding, it is compact and not lossy.


सिर्फ यह दिखाने के लिए कि मेहर्रद के ध्वनि share काम करते हैं, उनका दृष्टिकोण [BinaryFormatter को भी जारी रख सकता है (जिनमें से कई ने मेरे उत्तर के खिलाफ स्तर बनाया है, लेकिन जिनमें से हर कोई समान रूप से दोषी है, उदाहरण के लिए System.Text.Encoding.UTF8.GetBytes , System.Text.Encoding.Unicode.GetBytes ; उन एन्कोडिंग विधियों उदाहरण के लिए उच्च सरोगेट वर्ण d800 जारी नहीं रख सकते हैं, और वे केवल उच्च सरोगेट वर्णों को मूल्य fffd साथ fffd ):

using System;

class Program
{     
    static void Main(string[] args)
    {
        string t = "爱虫";            
        string s = "Test\ud800Test"; 

        byte[] dumpToBytes = GetBytes(s);
        string getItBack = GetString(dumpToBytes);

        foreach (char item in getItBack)
        {
            Console.WriteLine("{0} {1}", item, ((ushort)item).ToString("x"));
        }    
    }

    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }

    static string GetString(byte[] bytes)
    {
        char[] chars = new char[bytes.Length / sizeof(char)];
        System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }        
}

आउटपुट:

T 54
e 65
s 73
t 74
? d800
T 54
e 65
s 73
t 74

इसे System.Text.Encoding.UTF8.GetBytes या System.Text.Encoding.Unicode.GetBytes के साथ आज़माएं, वे केवल उच्च सरोगेट वर्णों को मूल्य fffd के साथ प्रतिस्थापित करेंगे

हर बार इस सवाल में एक आंदोलन होता है, मैं अभी भी एक धारावाहिक (यह माइक्रोसॉफ्ट से या तीसरे पक्ष के घटक से) के बारे में सोच रहा हूं जो तारों को जारी रख सकता है, यहां तक ​​कि इसमें अनपेक्षित सरोगेट पात्र भी शामिल हैं; मैं इसे हर बार और फिर Google पर करता हूं: serialization unpaired सरोगेट चरित्र .NET । इससे मुझे कोई नींद नहीं आती है, लेकिन यह हर तरह की परेशान होती है जब हर कोई और फिर मेरे जवाब पर कोई टिप्पणी करता है कि यह त्रुटिपूर्ण है, फिर भी जब उनके अनजान सरोगेट पात्रों की बात आती है तो उनके जवाब समान रूप से त्रुटिपूर्ण होते हैं।

डर्न, माइक्रोसॉफ्ट ने बस अपने BinaryFormatter में System.Buffer.BlockCopy का उपयोग किया होगा

谢谢!


यह composition बनाम inheritance का एक उत्कृष्ट उदाहरण है।

इस विशिष्ट मामले में:

क्या टीम जोड़े गए व्यवहार वाले खिलाड़ियों की एक सूची है

या

क्या टीम अपने आप का एक उद्देश्य है जो खिलाड़ियों की एक सूची होती है।

सूची विस्तार करके आप अपने आप को कई तरीकों से सीमित कर रहे हैं:

  1. आप पहुंच प्रतिबंधित नहीं कर सकते (उदाहरण के लिए, रोस्टर बदलने वाले लोगों को रोकना)। आपको सभी सूची विधियां मिलती हैं चाहे आपको उनकी आवश्यकता है या नहीं।

  2. क्या होता है यदि आप अन्य चीजों की सूचियां भी चाहते हैं। उदाहरण के लिए, टीमों के पास कोच, प्रबंधक, प्रशंसकों, उपकरण इत्यादि हैं। उनमें से कुछ अच्छी तरह से अपने अधिकार में सूचीबद्ध हो सकते हैं।

  3. आप विरासत के लिए अपने विकल्पों को सीमित करते हैं। उदाहरण के लिए आप एक सामान्य टीम ऑब्जेक्ट बनाना चाहते हैं, और उसके बाद बेसबॉल टीम, फुटबॉल टीम इत्यादि हो सकते हैं। सूची से प्राप्त करने के लिए आपको टीम से विरासत करने की आवश्यकता है, लेकिन इसका मतलब है कि सभी विभिन्न प्रकार की टीमों को उस रोस्टर के समान कार्यान्वयन के लिए मजबूर होना पड़ता है।

संरचना - आपके ऑब्जेक्ट के अंदर इच्छित व्यवहार देने वाली ऑब्जेक्ट सहित।

विरासत - आपकी वस्तु उस वस्तु का एक उदाहरण बन जाती है जिसमें आपके इच्छित व्यवहार होता है।

दोनों के पास उनके उपयोग हैं, लेकिन यह एक स्पष्ट मामला है जहां संरचना बेहतर है।







c# .net string