C# - Encoding.Default 값을 바꿀 수 있을까요?
아래와 같은 질문이 있는데,
런타임 시 Encoding.Default를 UTF-8로 설정할 수 있을까요?
; https://www.sysnet.pe.kr/3/0/5240
일단 DB Provider의 내용은 차치하고, 순수하게 Encoding.Default를 변경할 수 있는지에 대해 알아보겠습니다.
이를 위해 Reflection으로 Encoding.Default의 내용을 보면,
public static Encoding Default
{
[SecuritySafeCritical]
get
{
if (defaultEncoding == null)
{
defaultEncoding = CreateDefaultEncoding();
}
return defaultEncoding;
}
}
CreateDefaultEncoding이 호출되고 다시 그것을 보면,
[SecurityCritical]
private static Encoding CreateDefaultEncoding()
{
int aCP = Win32Native.GetACP();
switch (aCP)
{
case 1252:
return new SBCSCodePageEncoding(aCP);
case 65001:
return s_defaultUtf8EncodingNoBom;
default:
return GetEncoding(aCP);
}
}
결국 Win32 API인 GetACP에 의해 결정이 됩니다.
GetACP function
; https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getacp
이 함수는 시스템의 기본 ACP(ANSI Code page) id 값을 반환하므로 조정할 수 있는 방법이 없습니다. 가령 SetACP라는 Win32 API는 없고 제어판에서 code page 변경 후 시스템을 재시작해야 하는데 이에 대해서는 전에 관련 글을 쓴 적이 있습니다.
영문 설정의 Windows 10 명령행 창(cmd.exe)의 한글 지원
; https://www.sysnet.pe.kr/2/0/11559
그래도, 편법이 하나 있긴 합니다. ^^ Encoding.Default는 defaultEncoding 정적 필드의 값을 반환하는 것이기 때문에,
namespace System.Text
{
public abstract class Encoding : ICloneable
{
// ...[생략]...
private static volatile Encoding defaultEncoding;
// ...[생략]..
}
}
다음과 같이 Reflection으로 바꿔주면,
private static void SetDefaultEncoding(Encoding encoding)
{
Type type = typeof(System.Text.Encoding);
FieldInfo field = type.GetField("defaultEncoding", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
field.SetValue(null, encoding);
}
이렇게 사용할 수 있습니다.
static void Main(string[] args)
{
SetDefaultEncoding(Encoding.ASCII);
Console.WriteLine(Encoding.Default.EncodingName); // US-ASCII
SetDefaultEncoding(Encoding.UTF8);
Console.WriteLine(Encoding.Default.EncodingName); // Unicode (UTF-8)
}
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]