.NET Core 1.0~3.0의 핵심 .NET 라이브러리 호환성이 손상되는 변경
핵심 .NET 라이브러리는 .NET Core에서 사용되는 기본 형식과 기타 일반 형식을 제공합니다.
이 페이지에는 다음과 같은 주요 변경 사항이 설명되어 있습니다.
.NET Core 3.0
IEnumerable<T>를 사용하는 확장 메서드에 GroupCollection을 전달하려면 명확성 필요
GroupCollection에서 IEnumerable<T>
를 사용하는 확장 메서드를 호출하는 경우 캐스트를 사용하여 형식을 명확하게 해야 합니다.
변경 내용 설명
.NET Core 3.0부터 System.Text.RegularExpressions.GroupCollection은 구현하는 IEnumerable<Group>
을 비롯한 기타 형식 외에 IEnumerable<KeyValuePair<String,Group>>
도 구현합니다. 따라서 IEnumerable<T>를 사용하는 확장 메서드를 호출할 때 모호성이 발생합니다. GroupCollection 인스턴스에서 이러한 확장 메서드(예: Enumerable.Count)를 호출하는 경우 다음과 같은 컴파일러 오류가 표시됩니다.
CS1061: ‘GroupCollection’에 ‘Count’에 대한 정의가 없고 ‘GroupCollection’ 형식의 첫 번째 인수를 허용하는 액세스 가능한 확장 메서드 ‘Count’가 없습니다. using 지시문 또는 어셈블리 참조가 있는지 확인하세요.
이전 버전의 .NET에서는 모호성이 없어서 컴파일러 오류가 발생하지 않았습니다.
도입된 버전
3.0
변경 이유
이는 호환성이 손상되는 의도치 않은 변경이었습니다. 이와 같은 상황은 한동안 지속되어 왔으므로 되돌릴 계획이 없습니다. 또한 되돌리는 변경 자체로도 호환성이 손상될 수 있습니다.
권장 작업
GroupCollection 인스턴스의 경우 IEnumerable<T>
를 허용하는 확장 메서드의 호출을 캐스트를 사용하여 명확하게 합니다.
// Without a cast - causes CS1061.
match.Groups.Count(_ => true)
// With a disambiguating cast.
((IEnumerable<Group>)m.Groups).Count(_ => true);
범주
핵심 .NET 라이브러리
영향을 받는 API
IEnumerable<T>를 허용하는 모든 확장 메서드가 영향을 받습니다. 예시:
- System.Collections.Immutable.ImmutableArray.ToImmutableArray<TSource>(IEnumerable<TSource>)
- System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary
- System.Collections.Immutable.ImmutableHashSet.ToImmutableHashSet
- System.Collections.Immutable.ImmutableList.ToImmutableList<TSource>(IEnumerable<TSource>)
- System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary
- System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet
- System.Data.DataTableExtensions.CopyToDataTable
- 대부분의
System.Linq.Enumerable
메서드. 예: System.Linq.Enumerable.Count - System.Linq.ParallelEnumerable.AsParallel
- System.Linq.Queryable.AsQueryable
버전을 보고하는 API가 이제 파일 버전이 아닌 제품 버전을 보고함
.NET Core의 버전을 반환하는 대부분의 API가 이제 파일 버전이 아닌 제품 버전을 반환합니다.
변경 내용 설명
.NET Core 2.2 및 이전 버전에서는 Environment.Version, RuntimeInformation.FrameworkDescription 등의 메서드와 .NET Core 어셈블리의 파일 속성 대화 상자에 파일 버전이 반영됩니다. .NET Core 3.0부터는 제품 버전이 반영됩니다.
다음 그림은 Windows 탐색기 파일 속성 대화 상자에 표시되는 .NET Core 2.2(왼쪽) 및 .NET Core 3.0(오른쪽)에 대한 System.Runtime.dll 어셈블리의 버전 정보 차이를 보여 줍니다.
도입된 버전
3.0
권장 작업
없음 이 변경을 통해 직관적인 버전 검색이 가능합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
사용자 지정 EncoderFallbackBuffer 인스턴스는 재귀적으로 대체될 수 없음
사용자 지정 EncoderFallbackBuffer 인스턴스는 재귀적으로 대체될 수 없습니다. EncoderFallbackBuffer.GetNextChar()를 구현하면 대상 인코딩으로 변환할 수 있는 문자 시퀀스가 생겨야 합니다. 그렇지 않으면 예외가 발생합니다.
변경 내용 설명
런타임은 문자-바이트 트랜스코딩 작업 도중 형식이 잘못되었거나 변환할 수 없는 UTF-16 시퀀스를 검색하여 해당 문자를 EncoderFallbackBuffer.Fallback 메서드에 제공합니다. Fallback
메서드는 변환할 수 없는 원래 데이터를 대체할 문자를 결정하며, 이러한 문자는 루프에서 EncoderFallbackBuffer.GetNextChar를 호출하여 드레이닝됩니다.
그런 다음 런타임은 이러한 대체 문자를 대상 인코딩으로 트랜스코딩하려고 합니다. 이 작업이 성공하면 런타임은 원래 입력 문자열에서 중단된 위치에서 트랜스코딩을 계속 실행합니다.
이전에는 EncoderFallbackBuffer.GetNextChar()에 대한 사용자 지정 구현은 대상 인코딩으로 변환할 수 없는 문자 시퀀스를 반환할 수 있습니다. 대체된 문자를 대상 인코딩으로 변환할 수 없는 경우 런타임은 대체 문자를 사용하여 EncoderFallbackBuffer.Fallback 메서드를 다시 한 번 호출하여 EncoderFallbackBuffer.GetNextChar() 메서드가 새 대체 시퀀스를 반환할 것을 예상합니다. 이 프로세스는 런타임이 올바른 형식의 변환 가능한 대체를 확인하거나 최대 재귀 횟수에 도달할 때까지 계속됩니다.
.Net Core 3.0부터 EncoderFallbackBuffer.GetNextChar()에 대한 사용자 지정 구현은 대상 인코딩으로 변환할 수 있는 문자 시퀀스를 반환해야 합니다. 대체된 문자를 대상 인코딩으로 트랜스 코딩할 수 없으면 ArgumentException이 throw됩니다. 런타임은 더 이상 EncoderFallbackBuffer 인스턴스에 대한 재귀 호출을 수행하지 않습니다.
이 동작은 다음 조건 중 세 가지를 모두 충족하는 경우에만 적용됩니다.
- 런타임은 잘못된 형식의 UTF-16 시퀀스 또는 대상 인코딩으로 변환할 수 없는 UTF-16 시퀀스를 검색합니다.
- 사용자 지정 EncoderFallback이 지정되었습니다.
- 사용자 지정 EncoderFallback은 잘못된 형식이거나 변환할 수 없는 새 UTF-16 시퀀스를 대체하려고 시도합니다.
도입된 버전
3.0
권장 작업
대부분의 개발자는 아무 작업도 수행하지 않아도 됩니다.
애플리케이션이 사용자 지정 EncoderFallback 및 EncoderFallbackBuffer 클래스를 사용하는 경우 런타임이 처음 Fallback 메서드를 호출할 때 EncoderFallbackBuffer.Fallback 구현이 대상 인코딩으로 직접 변환할 수 있는 올바른 형식의 UTF-16 데이터로 대체 버퍼를 채우도록 합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
부동 소수점 서식 및 구문 분석 동작 변경됨
이제 부동 소수점 구문 분석 및 서식 동작(Double 및 Single 형식 사용)이 IEEE 규격으로 변경되었습니다. 따라서 .NET의 부동 소수점 형식 동작이 기타 IEEE 규격 언어의 동작과 일치합니다. 예를 들어 double.Parse("SomeLiteral")
는 항상 C#에서 double x = SomeLiteral
에 대해 생성하는 것과 일치해야 합니다.
변경 내용 설명
.NET Core 2.2 및 이전 버전에서는 Double.ToString 및 Single.ToString을 사용한 서식과 Double.Parse, Double.TryParse, Single.Parse, Single.TryParse을 사용한 구문 분석이 IEEE 규격이 아닙니다. 따라서 지원되는 표준 또는 사용자 지정 형식 문자열로 값이 왕복한다고 보장할 수 없습니다. 입력에 따라 서식이 지정된 값을 구문 분석하려는 시도가 실패하는 경우도 있고, 구문 분석된 값이 원래 값과 달라지는 경우도 있습니다.
.NET Core 3.0부터는 부동 소수점 구문 분석 및 서식 작업이 IEEE 754 규격입니다.
다음 표에서는 두 개의 코드 조각과 .NET Core 2.2와 .NET Core 3.1 사이에서 출력이 어떻게 변경되는지를 보여줍니다.
코드 조각 | .NET Core 2.2에서의 출력 | .NET Core 3.1에서의 출력 |
---|---|---|
Console.WriteLine((-0.0).ToString()); |
0 | -0 |
var value = -3.123456789123456789; Console.WriteLine(value == double.Parse(value.ToString())); |
False |
True |
자세한 내용은 Floating-point parsing and formatting improvements in .NET Core 3.0(.NET Core 3.0의 부동 소수점 구문 분석 및 서식 개선 사항)에 대한 블로그 게시물을 참조하세요.
도입된 버전
3.0
권장 작업
.NET Core 3.0의 부동 소수점 구문 분석 및 서식 개선 사항 블로그 게시물의 기존 코드에 미치는 잠재적 영향 섹션에서는 이전 동작을 유지하고자 하는 경우 코드에 대해 수행할 수 있는 몇 가지 변경 사항을 제안합니다.
- 서식에서의 일부 차이점의 경우 다른 서식 문자열을 지정하여 이전 동작과 동일한 동작을 가져올 수 있습니다.
- 구문 분석에서의 차이점의 경우 이전 동작으로 되돌릴 메커니즘이 없습니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
부동 소수점 구문 분석 작업은 더 이상 실패하거나 OverflowException을 throw하지 않음
부동 소수점 구문 분석 메서드는 더 이상 OverflowException을 throw하지 않거나, 숫자 값이 Single 또는 Double 부동 소수점 형식의 범위를 벗어난 문자열을 구문 분석할 때 false
를 반환합니다.
변경 내용 설명
.NET Core 2.2 및 이전 버전에서 Double.Parse 및 Single.Parse 메서드는 해당 형식의 범위를 벗어난 값에 대해 OverflowException를 throw합니다. Double.TryParse 및 Single.TryParse 메서드는 범위를 벗어난 숫자 값의 문자열 표현에 대해 false
를 반환합니다.
.NET Core 3.0부터 범위를 벗어난 숫자 문자열을 구문 분석할 때 Double.Parse, Double.TryParse, Single.Parse 및 Single.TryParse 메서드가 더 이상 실패하지 않습니다. 대신 Double 구문 분석 메서드는 Double.MaxValue를 초과하는 값에 대해 Double.PositiveInfinity를 반환하고 Double.MinValue보다 작은 값에 대해 Double.NegativeInfinity를 반환합니다. 마찬가지로 Single 구문 분석 메서드는 Single.MaxValue를 초과하는 값에 대해 Single.PositiveInfinity를 반환하고 Single.MinValue보다 작은 값에 대해 Single.NegativeInfinity를 반환합니다.
이러한 변경은 개정된 IEEE 754:2008 규정 준수를 위해 이루어졌습니다.
도입된 버전
3.0
권장 작업
이러한 변경 내용은 다음 두 가지 방법 중 하나로 코드에 영향을 줄 수 있습니다.
코드는 오버플로가 발생할 때 실행되는 OverflowException에 대한 처리기에 따라 다릅니다. 이 경우
catch
문을 제거하고 Double.IsInfinity 또는 Single.IsInfinity가true
인지 여부를 테스트하는If
문에 필요한 코드를 넣어야 합니다.코드에서 부동 소수점 값이
Infinity
가 아니라고 가정합니다. 이 경우PositiveInfinity
및NegativeInfinity
의 부동 소수점 값을 확인하는 데 필요한 코드를 추가해야 합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
InvalidAsynchronousStateException이 다른 어셈블리로 이동됨
InvalidAsynchronousStateException 클래스가 이동되었습니다.
변경 내용 설명
.NET Core 2.2 및 이전 버전에서는 InvalidAsynchronousStateException 클래스가 System.ComponentModel.TypeConverter 어셈블리에 있습니다.
.NET Core 3.0부터는 System.ComponentModel.Primitives 어셈블리에 있습니다.
도입된 버전
3.0
권장 작업
이 변경은 Assembly.GetType등의 메서드나 형식이 특정 어셈블리에 있다고 가정하는 Activator.CreateInstance 오버로드를 호출하여 리플렉션을 통해 InvalidAsynchronousStateException을 로드하는 애플리케이션에만 영향을 줍니다. 이 경우에는 메서드 호출에서 참조된 어셈블리를 업데이트하여 형식의 새 어셈블리 위치를 반영합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
없음
잘못된 형식의 UTF-8바이트 시퀀스 교체는 유니코드 지침을 따름
바이트-문자 코드 변환 작업 중에 UTF8Encoding 클래스에서 형식이 잘못된 UTF-8바이트 시퀀스가 있는 경우 출력 문자열에서 이 시퀀스가 '�' 문자(U+FFFD 대체 문자)로 바뀝니다. .NET Core 3.0은 이전 버전의 .NET Core 및 .NET Framework와 달리 트랜스코딩 작업 도중 이 대체를 수행하기 위해 유니코드 모범 사례를 따릅니다.
이는 새로운 System.Text.Unicode.Utf8 및 System.Text.Rune 형식을 포함하여 .NET 전체에서 UTF-8 처리를 향상하기 위해 기울인 보다 많은 노력의 일환입니다. UTF8Encoding 형식에는 새로 도입된 형식과 일치하는 출력을 생성하도록 향상된 오류 처리 메커니즘이 적용되었습니다.
변경 내용 설명
.Net Core 3.0부터 바이트를 문자로 트랜스코딩하는 경우 UTF8Encoding 클래스는 유니코드 모범 사례를 기반으로 문자 대체를 수행합니다. 사용되는 대체 메커니즘은 최대 하위 부분의 U+FFFD 대체 항목의 유니코드 표준 버전 12.0, 섹션 3.9(PDF)에서 설명합니다.
이 동작은 입력 바이트 시퀀스에 잘못된 형식의 UTF-8 데이터가 포함된 경우에만 적용됩니다. 또한 UTF8Encoding 인스턴스가 throwOnInvalidBytes: true
를 사용하여 구성된 경우 UTF8Encoding
인스턴스는 U+FFFD 대체를 수행하는 대신 잘못된 입력에 대해 계속 throw합니다. UTF8Encoding
생성자에 대한 자세한 내용은 UTF8Encoding(Boolean, Boolean)를 참조하세요.
다음 표에서는 잘못된 3바이트 입력으로 인한 이 변경의 영향을 보여줍니다.
잘못된 형식의 3바이트 입력 | .NET Core 3.0 이하의 출력 | .NET Core 3.0 이상의 출력 |
---|---|---|
[ ED A0 90 ] |
[ FFFD FFFD ] (2자 출력) |
[ FFFD FFFD FFFD ] (3자 출력) |
3자 출력은 위에 링크된 유니코드 표준 PDF의 표 3-9에 따라 선호되는 출력입니다.
도입된 버전
3.0
권장 작업
개발자는 아무 작업도 수행하지 않아도 됩니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
TypeDescriptionProviderAttribute가 다른 어셈블리로 이동됨
TypeDescriptionProviderAttribute 클래스가 이동되었습니다.
변경 내용 설명
.NET Core 2.2 및 이전 버전에서는 TypeDescriptionProviderAttribute 클래스가 System.ComponentModel.TypeConverter 어셈블리에 있습니다.
.NET Core 3.0부터는 System.ObjectModel 어셈블리에 있습니다.
도입된 버전
3.0
권장 작업
이 변경은 Assembly.GetType등의 메서드나 형식이 특정 어셈블리에 있다고 가정하는 Activator.CreateInstance 오버로드를 호출하여 리플렉션을 통해 TypeDescriptionProviderAttribute 형식을 로드하는 애플리케이션에만 영향을 줍니다. 이 경우에는 메서드 호출에서 참조된 어셈블리를 형식의 새 어셈블리 위치에 맞게 업데이트해야 합니다.
범주
Windows Forms
영향을 받는 API
없음
ZipArchiveEntry가 더 이상 일치하지 않는 항목 크기의 아카이브를 처리하지 않음
Zip 보관 파일은 중앙 디렉터리 및 로컬 헤더에 압축 크기와 압축되지 않은 크기를 모두 나열합니다. 항목 데이터 자체도 크기를 표시합니다. .NET Core 2.2 버전 이하에서는 이러한 값에 대해 일관성을 검사하지 않았습니다. .NET Core 3.0부터는 검사됩니다.
변경 내용 설명
.Net Core 2.2 버전 이하에서는 로컬 헤더가 zip 파일의 중앙 헤더와 일치하지 않는 경우에도 ZipArchiveEntry.Open()이 성공합니다. 데이터는 압축된 스트림의 끝에 도달할 때까지 압축이 풀립니다. 이는 해당 길이가 중앙 디렉터리/로컬 헤더에 나열된 압축되지 않은 파일 크기를 초과하는 경우에도 마찬가지입니다.
.Net Core 3.0부터 ZipArchiveEntry.Open() 메서드는 로컬 헤더 및 중앙 헤더에서 항목의 압축된 크기와 압축되지 않은 크기가 일치하는지 확인합니다. 보관 파일의 로컬 헤더 및/또는 데이터 설명자가 zip 파일의 중앙 디렉터리와 일치하지 않는 크기를 나열하는 경우 메서드가 InvalidDataException을 throw합니다. 항목을 읽을 때 압축 해제된 데이터가 헤더에 나열된 압축되지 않은 파일 크기로 잘립니다.
이러한 변경은 ZipArchiveEntry가 해당 데이터의 크기를 정확하게 표시하고 해당 양의 데이터만 읽도록 하기 위함입니다.
도입된 버전
3.0
권장 작업
이러한 문제가 발생하는 zip 보관 파일을 다시 패키지합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
- ZipArchiveEntry.Open()
- ZipFileExtensions.ExtractToDirectory
- ZipFileExtensions.ExtractToFile
- ZipFile.ExtractToDirectory
FieldInfo.SetValue가 초기화 전용 정적 필드에 대해 예외를 throw
.NET Core 3.0부터 System.Reflection.FieldInfo.SetValue를 호출하여 정적 InitOnly 필드에 값을 설정하려고 하면 예외가 throw됩니다.
변경 내용 설명
.NET Framework 및 3.0 이전 버전의 .NET Core에서는 System.Reflection.FieldInfo.SetValue을 호출하여 초기화 후 상수인 정적 필드의 값을 설정할 수 있습니다(C#의 readonly). 그러나 이러한 필드를 이 방식으로 설정하면 대상 프레임워크 및 최적화 설정에 따라 예기치 않은 동작이 발생합니다.
.NET Core 3.0 이상 버전에서 정적 InitOnly 필드에 SetValue를 호출하면 System.FieldAccessException 예외가 throw됩니다.
팁
InitOnly 필드는 선언되는 시점에 또는 포함하는 클래스의 생성자에서만 설정할 수 있는 필드입니다. 즉, 초기화 후에는 상수입니다.
도입된 버전
3.0
권장 작업
정적 생성자에서 정적 InitOnly 필드를 초기화합니다. 이는 동적 형식과 비동적 형식 모두에 적용됩니다.
또는 필드에서 FieldAttributes.InitOnly 특성을 제거한 다음 FieldInfo.SetValue를 호출할 수 있습니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
- FieldInfo.SetValue(Object, Object)
- FieldInfo.SetValue(Object, Object, BindingFlags, Binder, CultureInfo)
.NET Core 2.1
경로 API가 잘못된 문자에 대해 예외를 throw하지 않음
파일 경로와 관련된 API는 잘못된 문자가 발견된 경우 더 이상 경로 문자의 유효성을 검사하거나 ArgumentException을 throw하지 않습니다.
변경 내용 설명
.NET Framework 및 .NET Core 1.0~2.0에서는 경로 인수에 잘못된 경로 문자가 포함된 경우 영향을 받는 API 섹션에 나열된 메서드가 ArgumentException을 throw합니다. .NET Core 2.1부터 잘못된 문자가 발견된 경우 이 메서드는 더 이상 잘못된 경로 문자를 검사하거나 예외를 throw하지 않습니다.
변경 이유
경로 문자의 적극적 유효성 검사는 일부 플랫폼 간 시나리오를 차단합니다. .NET에서 운영 체제 API 호출 결과를 복제하거나 예측하지 않도록 이 변경 내용이 도입되었습니다. 자세한 내용은 .NET Core 2.1의 System.IO 살펴보기 블로그 게시물을 참조하세요.
도입된 버전
.NET Core 2.1
권장 작업
코드가 이 API를 사용하여 잘못된 문자를 검사한 경우 Path.GetInvalidPathChars 호출을 추가할 수 있습니다.
영향을 받는 API
- System.IO.Directory.CreateDirectory
- System.IO.Directory.Delete
- System.IO.Directory.EnumerateDirectories
- System.IO.Directory.EnumerateFiles
- System.IO.Directory.EnumerateFileSystemEntries
- System.IO.Directory.GetCreationTime(String)
- System.IO.Directory.GetCreationTimeUtc(String)
- System.IO.Directory.GetDirectories
- System.IO.Directory.GetDirectoryRoot(String)
- System.IO.Directory.GetFiles
- System.IO.Directory.GetFileSystemEntries
- System.IO.Directory.GetLastAccessTime(String)
- System.IO.Directory.GetLastAccessTimeUtc(String)
- System.IO.Directory.GetLastWriteTime(String)
- System.IO.Directory.GetLastWriteTimeUtc(String)
- System.IO.Directory.GetParent(String)
- System.IO.Directory.Move(String, String)
- System.IO.Directory.SetCreationTime(String, DateTime)
- System.IO.Directory.SetCreationTimeUtc(String, DateTime)
- System.IO.Directory.SetCurrentDirectory(String)
- System.IO.Directory.SetLastAccessTime(String, DateTime)
- System.IO.Directory.SetLastAccessTimeUtc(String, DateTime)
- System.IO.Directory.SetLastWriteTime(String, DateTime)
- System.IO.Directory.SetLastWriteTimeUtc(String, DateTime)
- System.IO.DirectoryInfo ctor
- System.IO.Directory.GetDirectories
- System.IO.Directory.GetFiles
- System.IO.DirectoryInfo.GetFileSystemInfos
- System.IO.File.AppendAllText
- System.IO.File.AppendAllTextAsync
- System.IO.File.Copy
- System.IO.File.Create
- System.IO.File.CreateText
- System.IO.File.Decrypt
- System.IO.File.Delete
- System.IO.File.Encrypt
- System.IO.File.GetAttributes(String)
- System.IO.File.GetCreationTime(String)
- System.IO.File.GetCreationTimeUtc(String)
- System.IO.File.GetLastAccessTime(String)
- System.IO.File.GetLastAccessTimeUtc(String)
- System.IO.File.GetLastWriteTime(String)
- System.IO.File.GetLastWriteTimeUtc(String)
- System.IO.File.Move
- System.IO.File.Open
- System.IO.File.OpenRead(String)
- System.IO.File.OpenText(String)
- System.IO.File.OpenWrite(String)
- System.IO.File.ReadAllBytes(String)
- System.IO.File.ReadAllBytesAsync(String, CancellationToken)
- System.IO.File.ReadAllLines(String)
- System.IO.File.ReadAllLinesAsync(String, CancellationToken)
- System.IO.File.ReadAllText(String)
- System.IO.File.ReadAllTextAsync(String, CancellationToken)
- System.IO.File.SetAttributes(String, FileAttributes)
- System.IO.File.SetCreationTime(String, DateTime)
- System.IO.File.SetCreationTimeUtc(String, DateTime)
- System.IO.File.SetLastAccessTime(String, DateTime)
- System.IO.File.SetLastAccessTimeUtc(String, DateTime)
- System.IO.File.SetLastWriteTime(String, DateTime)
- System.IO.File.SetLastWriteTimeUtc(String, DateTime)
- System.IO.File.WriteAllBytes(String, Byte[])
- System.IO.File.WriteAllBytesAsync(String, Byte[], CancellationToken)
- System.IO.File.WriteAllLines
- System.IO.File.WriteAllLinesAsync
- System.IO.File.WriteAllText
- System.IO.FileInfo ctor
- System.IO.FileInfo.CopyTo
- System.IO.FileInfo.MoveTo
- System.IO.FileStream ctor
- System.IO.Path.GetFullPath(String)
- System.IO.Path.IsPathRooted(String)
- System.IO.Path.GetPathRoot(String)
- System.IO.Path.ChangeExtension(String, String)
- System.IO.Path.GetDirectoryName(String)
- System.IO.Path.GetExtension(String)
- System.IO.Path.HasExtension(String)
- System.IO.Path.Combine
참고 항목
기본 제공 구조체 형식에 추가된 프라이빗 필드
프라이빗 필드가 참조 어셈블리의 특정 구조체 형식에 추가되었습니다. 그 결과 C#에서 이러한 구조체 형식은 항상 new 연산자 또는 기본 리터럴을 사용하여 인스턴스화해야 합니다.
변경 내용 설명
.NET Core 2.0 및 이전 버전에서 제공되는 일부 구조체 형식(예: ConsoleKeyInfo)은 C#에서 new
연산자 또는 기본 리터럴을 사용하지 않고도 인스턴스화할 수 있습니다. 이는 C# 컴파일러에서 사용하는 참조 어셈블리에 구조체에 대한 프라이빗 필드가 포함되지 않았기 때문입니다. .NET 구조체 형식에 대한 모든 프라이빗 필드는 .NET Core 2.1에서 시작하는 참조 어셈블리에 추가됩니다.
예를 들어 다음 C# 코드는 .NET Core 2.0에서 컴파일되지만 .NET Core 2.1에서는 컴파일되지 않습니다.
ConsoleKeyInfo key; // Struct type
if (key.ToString() == "y")
{
Console.WriteLine("Yes!");
}
.NET Core 2.1에서 이전 코드로 인해 CS0165 - 할당되지 않은 지역 변수 'key' 사용 컴파일러 오류가 발생합니다.
도입된 버전
2.1
권장 작업
new
연산자 또는 기본 리터럴을 사용하여 구조체 형식을 인스턴스화합니다.
예시:
ConsoleKeyInfo key = new ConsoleKeyInfo(); // Struct type.
if (key.ToString() == "y")
Console.WriteLine("Yes!");
ConsoleKeyInfo key = default; // Struct type.
if (key.ToString() == "y")
Console.WriteLine("Yes!");
범주
핵심 .NET 라이브러리
영향을 받는 API
- System.ArraySegment<T>.Enumerator
- System.ArraySegment<T>
- System.Boolean
- System.Buffers.MemoryHandle
- System.Buffers.StandardFormat
- System.Byte
- System.Char
- System.Collections.DictionaryEntry
- System.Collections.Generic.Dictionary<TKey,TValue>.Enumerator
- System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.Enumerator
- System.Collections.Generic.Dictionary<TKey,TValue>.ValueCollection.Enumerator
- System.Collections.Generic.HashSet<T>.Enumerator
- System.Collections.Generic.KeyValuePair<TKey,TValue>
- System.Collections.Generic.LinkedList<T>.Enumerator
- System.Collections.Generic.List<T>.Enumerator
- System.Collections.Generic.Queue<T>.Enumerator
- System.Collections.Generic.SortedDictionary<TKey,TValue>.Enumerator
- System.Collections.Generic.SortedDictionary<TKey,TValue>.KeyCollection.Enumerator
- System.Collections.Generic.SortedDictionary<TKey,TValue>.ValueCollection.Enumerator
- System.Collections.Generic.SortedSet<T>.Enumerator
- System.Collections.Generic.Stack<T>.Enumerator
- System.Collections.Immutable.ImmutableArray<T>.Enumerator
- System.Collections.Immutable.ImmutableArray<T>
- System.Collections.Immutable.ImmutableDictionary<TKey,TValue>.Enumerator
- System.Collections.Immutable.ImmutableHashSet<T>.Enumerator
- System.Collections.Immutable.ImmutableList<T>.Enumerator
- System.Collections.Immutable.ImmutableQueue<T>.Enumerator
- System.Collections.Immutable.ImmutableSortedDictionary<TKey,TValue>.Enumerator
- System.Collections.Immutable.ImmutableSortedSet<T>.Enumerator
- System.Collections.Immutable.ImmutableStack<T>.Enumerator
- System.Collections.Specialized.BitVector32.Section
- System.Collections.Specialized.BitVector32
- LazyMemberInfo
- System.ComponentModel.Design.Serialization.MemberRelationship
- System.ConsoleKeyInfo
- System.Data.SqlTypes.SqlBinary
- System.Data.SqlTypes.SqlBoolean
- System.Data.SqlTypes.SqlByte
- System.Data.SqlTypes.SqlDateTime
- System.Data.SqlTypes.SqlDecimal
- System.Data.SqlTypes.SqlDouble
- System.Data.SqlTypes.SqlGuid
- System.Data.SqlTypes.SqlInt16
- System.Data.SqlTypes.SqlInt32
- System.Data.SqlTypes.SqlInt64
- System.Data.SqlTypes.SqlMoney
- System.Data.SqlTypes.SqlSingle
- System.Data.SqlTypes.SqlString
- System.DateTime
- System.DateTimeOffset
- System.Decimal
- System.Diagnostics.CounterSample
- System.Diagnostics.SymbolStore.SymbolToken
- System.Diagnostics.Tracing.EventSource.EventData
- System.Diagnostics.Tracing.EventSourceOptions
- System.Double
- System.Drawing.CharacterRange
- System.Drawing.Point
- System.Drawing.PointF
- System.Drawing.Rectangle
- System.Drawing.RectangleF
- System.Drawing.Size
- System.Drawing.SizeF
- System.Guid
- System.HashCode
- System.Int16
- System.Int32
- System.Int64
- System.IntPtr
- System.IO.Pipelines.FlushResult
- System.IO.Pipelines.ReadResult
- System.IO.WaitForChangedResult
- System.Memory<T>
- System.ModuleHandle
- System.Net.Security.SslApplicationProtocol
- System.Net.Sockets.IPPacketInformation
- System.Net.Sockets.SocketInformation
- System.Net.Sockets.UdpReceiveResult
- System.Net.WebSockets.ValueWebSocketReceiveResult
- System.Nullable<T>
- System.Numerics.BigInteger
- System.Numerics.Complex
- System.Numerics.Vector<T>
- System.ReadOnlyMemory<T>
- System.ReadOnlySpan<T>.Enumerator
- System.ReadOnlySpan<T>
- System.Reflection.CustomAttributeNamedArgument
- System.Reflection.CustomAttributeTypedArgument
- System.Reflection.Emit.Label
- System.Reflection.Emit.OpCode
- System.Reflection.Metadata.ArrayShape
- System.Reflection.Metadata.AssemblyDefinition
- System.Reflection.Metadata.AssemblyDefinitionHandle
- System.Reflection.Metadata.AssemblyFile
- System.Reflection.Metadata.AssemblyFileHandle
- System.Reflection.Metadata.AssemblyFileHandleCollection.Enumerator
- System.Reflection.Metadata.AssemblyFileHandleCollection
- System.Reflection.Metadata.AssemblyReference
- System.Reflection.Metadata.AssemblyReferenceHandle
- System.Reflection.Metadata.AssemblyReferenceHandleCollection.Enumerator
- System.Reflection.Metadata.AssemblyReferenceHandleCollection
- System.Reflection.Metadata.Blob
- System.Reflection.Metadata.BlobBuilder.Blobs
- System.Reflection.Metadata.BlobContentId
- System.Reflection.Metadata.BlobHandle
- System.Reflection.Metadata.BlobReader
- System.Reflection.Metadata.BlobWriter
- System.Reflection.Metadata.Constant
- System.Reflection.Metadata.ConstantHandle
- System.Reflection.Metadata.CustomAttribute
- System.Reflection.Metadata.CustomAttributeHandle
- System.Reflection.Metadata.CustomAttributeHandleCollection.Enumerator
- System.Reflection.Metadata.CustomAttributeHandleCollection
- System.Reflection.Metadata.CustomAttributeNamedArgument<TType>
- System.Reflection.Metadata.CustomAttributeTypedArgument<TType>
- System.Reflection.Metadata.CustomAttributeValue<TType>
- System.Reflection.Metadata.CustomDebugInformation
- System.Reflection.Metadata.CustomDebugInformationHandle
- System.Reflection.Metadata.CustomDebugInformationHandleCollection.Enumerator
- System.Reflection.Metadata.CustomDebugInformationHandleCollection
- System.Reflection.Metadata.DeclarativeSecurityAttribute
- System.Reflection.Metadata.DeclarativeSecurityAttributeHandle
- System.Reflection.Metadata.DeclarativeSecurityAttributeHandleCollection.Enumerator
- System.Reflection.Metadata.DeclarativeSecurityAttributeHandleCollection
- System.Reflection.Metadata.Document
- System.Reflection.Metadata.DocumentHandle
- System.Reflection.Metadata.DocumentHandleCollection.Enumerator
- System.Reflection.Metadata.DocumentHandleCollection
- System.Reflection.Metadata.DocumentNameBlobHandle
- System.Reflection.Metadata.Ecma335.ArrayShapeEncoder
- System.Reflection.Metadata.Ecma335.BlobEncoder
- System.Reflection.Metadata.Ecma335.CustomAttributeArrayTypeEncoder
- System.Reflection.Metadata.Ecma335.CustomAttributeElementTypeEncoder
- System.Reflection.Metadata.Ecma335.CustomAttributeNamedArgumentsEncoder
- System.Reflection.Metadata.Ecma335.CustomModifiersEncoder
- System.Reflection.Metadata.Ecma335.EditAndContinueLogEntry
- System.Reflection.Metadata.Ecma335.ExceptionRegionEncoder
- System.Reflection.Metadata.Ecma335.FixedArgumentsEncoder
- System.Reflection.Metadata.Ecma335.GenericTypeArgumentsEncoder
- System.Reflection.Metadata.Ecma335.InstructionEncoder
- System.Reflection.Metadata.Ecma335.LabelHandle
- System.Reflection.Metadata.Ecma335.LiteralEncoder
- System.Reflection.Metadata.Ecma335.LiteralsEncoder
- System.Reflection.Metadata.Ecma335.LocalVariablesEncoder
- System.Reflection.Metadata.Ecma335.LocalVariableTypeEncoder
- System.Reflection.Metadata.Ecma335.MethodBodyStreamEncoder.MethodBody
- System.Reflection.Metadata.Ecma335.MethodBodyStreamEncoder
- System.Reflection.Metadata.Ecma335.MethodSignatureEncoder
- System.Reflection.Metadata.Ecma335.NamedArgumentsEncoder
- System.Reflection.Metadata.Ecma335.NamedArgumentTypeEncoder
- System.Reflection.Metadata.Ecma335.NameEncoder
- System.Reflection.Metadata.Ecma335.ParametersEncoder
- System.Reflection.Metadata.Ecma335.ParameterTypeEncoder
- System.Reflection.Metadata.Ecma335.PermissionSetEncoder
- System.Reflection.Metadata.Ecma335.ReturnTypeEncoder
- System.Reflection.Metadata.Ecma335.ScalarEncoder
- System.Reflection.Metadata.Ecma335.SignatureDecoder<TType,TGenericContext>
- System.Reflection.Metadata.Ecma335.SignatureTypeEncoder
- System.Reflection.Metadata.Ecma335.VectorEncoder
- System.Reflection.Metadata.EntityHandle
- System.Reflection.Metadata.EventAccessors
- System.Reflection.Metadata.EventDefinition
- System.Reflection.Metadata.EventDefinitionHandle
- System.Reflection.Metadata.EventDefinitionHandleCollection.Enumerator
- System.Reflection.Metadata.EventDefinitionHandleCollection
- System.Reflection.Metadata.ExceptionRegion
- System.Reflection.Metadata.ExportedType
- System.Reflection.Metadata.ExportedTypeHandle
- System.Reflection.Metadata.ExportedTypeHandleCollection.Enumerator
- System.Reflection.Metadata.ExportedTypeHandleCollection
- System.Reflection.Metadata.FieldDefinition
- System.Reflection.Metadata.FieldDefinitionHandle
- System.Reflection.Metadata.FieldDefinitionHandleCollection.Enumerator
- System.Reflection.Metadata.FieldDefinitionHandleCollection
- System.Reflection.Metadata.GenericParameter
- System.Reflection.Metadata.GenericParameterConstraint
- System.Reflection.Metadata.GenericParameterConstraintHandle
- System.Reflection.Metadata.GenericParameterConstraintHandleCollection.Enumerator
- System.Reflection.Metadata.GenericParameterConstraintHandleCollection
- System.Reflection.Metadata.GenericParameterHandle
- System.Reflection.Metadata.GenericParameterHandleCollection.Enumerator
- System.Reflection.Metadata.GenericParameterHandleCollection
- System.Reflection.Metadata.GuidHandle
- System.Reflection.Metadata.Handle
- System.Reflection.Metadata.ImportDefinition
- System.Reflection.Metadata.ImportDefinitionCollection.Enumerator
- System.Reflection.Metadata.ImportDefinitionCollection
- System.Reflection.Metadata.ImportScope
- System.Reflection.Metadata.ImportScopeCollection.Enumerator
- System.Reflection.Metadata.ImportScopeCollection
- System.Reflection.Metadata.ImportScopeHandle
- System.Reflection.Metadata.InterfaceImplementation
- System.Reflection.Metadata.InterfaceImplementationHandle
- System.Reflection.Metadata.InterfaceImplementationHandleCollection.Enumerator
- System.Reflection.Metadata.InterfaceImplementationHandleCollection
- System.Reflection.Metadata.LocalConstant
- System.Reflection.Metadata.LocalConstantHandle
- System.Reflection.Metadata.LocalConstantHandleCollection.Enumerator
- System.Reflection.Metadata.LocalConstantHandleCollection
- System.Reflection.Metadata.LocalScope
- System.Reflection.Metadata.LocalScopeHandle
- System.Reflection.Metadata.LocalScopeHandleCollection.ChildrenEnumerator
- System.Reflection.Metadata.LocalScopeHandleCollection.Enumerator
- System.Reflection.Metadata.LocalScopeHandleCollection
- System.Reflection.Metadata.LocalVariable
- System.Reflection.Metadata.LocalVariableHandle
- System.Reflection.Metadata.LocalVariableHandleCollection.Enumerator
- System.Reflection.Metadata.LocalVariableHandleCollection
- System.Reflection.Metadata.ManifestResource
- System.Reflection.Metadata.ManifestResourceHandle
- System.Reflection.Metadata.ManifestResourceHandleCollection.Enumerator
- System.Reflection.Metadata.ManifestResourceHandleCollection
- System.Reflection.Metadata.MemberReference
- System.Reflection.Metadata.MemberReferenceHandle
- System.Reflection.Metadata.MemberReferenceHandleCollection.Enumerator
- System.Reflection.Metadata.MemberReferenceHandleCollection
- System.Reflection.Metadata.MetadataStringComparer
- System.Reflection.Metadata.MethodDebugInformation
- System.Reflection.Metadata.MethodDebugInformationHandle
- System.Reflection.Metadata.MethodDebugInformationHandleCollection.Enumerator
- System.Reflection.Metadata.MethodDebugInformationHandleCollection
- System.Reflection.Metadata.MethodDefinition
- System.Reflection.Metadata.MethodDefinitionHandle
- System.Reflection.Metadata.MethodDefinitionHandleCollection.Enumerator
- System.Reflection.Metadata.MethodDefinitionHandleCollection
- System.Reflection.Metadata.MethodImplementation
- System.Reflection.Metadata.MethodImplementationHandle
- System.Reflection.Metadata.MethodImplementationHandleCollection.Enumerator
- System.Reflection.Metadata.MethodImplementationHandleCollection
- System.Reflection.Metadata.MethodImport
- System.Reflection.Metadata.MethodSignature<TType>
- System.Reflection.Metadata.MethodSpecification
- System.Reflection.Metadata.MethodSpecificationHandle
- System.Reflection.Metadata.ModuleDefinition
- System.Reflection.Metadata.ModuleDefinitionHandle
- System.Reflection.Metadata.ModuleReference
- System.Reflection.Metadata.ModuleReferenceHandle
- System.Reflection.Metadata.NamespaceDefinition
- System.Reflection.Metadata.NamespaceDefinitionHandle
- System.Reflection.Metadata.Parameter
- System.Reflection.Metadata.ParameterHandle
- System.Reflection.Metadata.ParameterHandleCollection.Enumerator
- System.Reflection.Metadata.ParameterHandleCollection
- System.Reflection.Metadata.PropertyAccessors
- System.Reflection.Metadata.PropertyDefinition
- System.Reflection.Metadata.PropertyDefinitionHandle
- System.Reflection.Metadata.PropertyDefinitionHandleCollection.Enumerator
- System.Reflection.Metadata.PropertyDefinitionHandleCollection
- System.Reflection.Metadata.ReservedBlob<THandle>
- System.Reflection.Metadata.SequencePoint
- System.Reflection.Metadata.SequencePointCollection.Enumerator
- System.Reflection.Metadata.SequencePointCollection
- System.Reflection.Metadata.SignatureHeader
- System.Reflection.Metadata.StandaloneSignature
- System.Reflection.Metadata.StandaloneSignatureHandle
- System.Reflection.Metadata.StringHandle
- System.Reflection.Metadata.TypeDefinition
- System.Reflection.Metadata.TypeDefinitionHandle
- System.Reflection.Metadata.TypeDefinitionHandleCollection.Enumerator
- System.Reflection.Metadata.TypeDefinitionHandleCollection
- System.Reflection.Metadata.TypeLayout
- System.Reflection.Metadata.TypeReference
- System.Reflection.Metadata.TypeReferenceHandle
- System.Reflection.Metadata.TypeReferenceHandleCollection.Enumerator
- System.Reflection.Metadata.TypeReferenceHandleCollection
- System.Reflection.Metadata.TypeSpecification
- System.Reflection.Metadata.TypeSpecificationHandle
- System.Reflection.Metadata.UserStringHandle
- System.Reflection.ParameterModifier
- System.Reflection.PortableExecutable.CodeViewDebugDirectoryData
- System.Reflection.PortableExecutable.DebugDirectoryEntry
- System.Reflection.PortableExecutable.PEMemoryBlock
- System.Reflection.PortableExecutable.SectionHeader
- System.Runtime.CompilerServices.AsyncTaskMethodBuilder<TResult>
- System.Runtime.CompilerServices.AsyncTaskMethodBuilder
- System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder<TResult>
- System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder
- System.Runtime.CompilerServices.AsyncVoidMethodBuilder
- System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter
- System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult>
- System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter
- System.Runtime.CompilerServices.ConfiguredTaskAwaitable
- System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<TResult>
- System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<TResult>.ConfiguredValueTaskAwaiter
- System.Runtime.CompilerServices.TaskAwaiter<TResult>
- System.Runtime.CompilerServices.TaskAwaiter
- System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>
- System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>
- System.Runtime.InteropServices.ArrayWithOffset
- System.Runtime.InteropServices.GCHandle
- System.Runtime.InteropServices.HandleRef
- System.Runtime.InteropServices.OSPlatform
- System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken
- System.Runtime.Serialization.SerializationEntry
- System.Runtime.Serialization.StreamingContext
- System.RuntimeArgumentHandle
- System.RuntimeFieldHandle
- System.RuntimeMethodHandle
- System.RuntimeTypeHandle
- System.SByte
- System.Security.Cryptography.CngProperty
- System.Security.Cryptography.ECCurve
- System.Security.Cryptography.HashAlgorithmName
- System.Security.Cryptography.X509Certificates.X509ChainStatus
- System.Security.Cryptography.Xml.X509IssuerSerial
- System.ServiceProcess.SessionChangeDescription
- System.Single
- System.Span<T>.Enumerator
- System.Span<T>
- System.Threading.AsyncFlowControl
- System.Threading.AsyncLocalValueChangedArgs<T>
- System.Threading.CancellationToken
- System.Threading.CancellationTokenRegistration
- System.Threading.LockCookie
- System.Threading.SpinLock
- System.Threading.SpinWait
- System.Threading.Tasks.Dataflow.DataflowMessageHeader
- System.Threading.Tasks.ParallelLoopResult
- System.Threading.Tasks.ValueTask<TResult>
- System.TimeSpan
- System.TimeZoneInfo.TransitionTime
- System.Transactions.TransactionOptions
- System.TypedReference
- System.TypedReference
- System.UInt16
- System.UInt32
- System.UInt64
- System.UIntPtr
- System.Windows.Forms.ColorDialog.Color
- System.Windows.Media.Animation.KeyTime
- System.Windows.Media.Animation.RepeatBehavior
- System.Xml.Serialization.XmlDeserializationEvents
- Windows.Foundation.Point
- Windows.Foundation.Rect
- Windows.Foundation.Size
- Windows.UI.Color
- Windows.UI.Xaml.Controls.Primitives.GeneratorPosition
- Windows.UI.Xaml.CornerRadius
- Windows.UI.Xaml.Duration
- Windows.UI.Xaml.GridLength
- Windows.UI.Xaml.Media.Matrix
- Windows.UI.Xaml.Media.Media3D.Matrix3D
- Windows.UI.Xaml.Thickness
UseShellExecute의 기본값 변경
ProcessStartInfo.UseShellExecute의 기본값은 .NET Core에서 false
입니다. .NET Framework에서의 기본값은 true
입니다.
변경 내용 설명
Process.Start 사용을 통해 애플리케이션을 직접 실행할 수 있습니다. 예를 들어 Process.Start("mspaint.exe")
와 같은 코드를 사용하면 그림판이 실행됩니다. ProcessStartInfo.UseShellExecute이 true
로 설정된 경우 연결된 애플리케이션을 간접적으로 시작할 수도 있습니다. .NET Framework에서 ProcessStartInfo.UseShellExecute의 기본값은 true
입니다. 따라서 해당 편집기를 사용하여 .txt과 연결한 경우 Process.Start("mytextfile.txt")
와 같은 코드로 메모장이 시작됩니다. .NET Framework에서 간접적으로 앱을 시작하는 것을 방지하려면 명시적으로 ProcessStartInfo.UseShellExecute을 false
로 설정해야 합니다. .NET Core에서 ProcessStartInfo.UseShellExecute의 기본값은 false
입니다. 따라서 기본적으로 Process.Start
를 호출할 때 연결된 애플리케이션이 시작되지 않습니다.
System.Diagnostics.ProcessStartInfo의 다음 속성은 ProcessStartInfo.UseShellExecute가 true
인 경우에만 작동합니다.
- ProcessStartInfo.CreateNoWindow
- ProcessStartInfo.ErrorDialog
- ProcessStartInfo.Verb
- ProcessStartInfo.WindowStyle.
이 변경 사항은 성능 사유로 인해 .NET Core에 도입되었습니다. 일반적으로 Process.Start은 애플리케이션을 직접 시작하는 데 사용됩니다. 앱을 직접 시작하는 경우 Windows 셸을 포함하지 않아도 되며 관련된 성능 비용도 발생하지 않습니다. 이 기본 사례를 더욱 빠르게 하도록 .NET Core는 ProcessStartInfo.UseShellExecute의 기본값을 false
로 변경합니다. 필요한 경우 느린 경로로 옵트인할 수 있습니다.
도입된 버전
2.1
참고 항목
이전 버전의 .NET Core에서 UseShellExecute
는 Windows에 구현되지 않았습니다.
권장 작업
앱이 이전 동작에 의존하는 경우 ProcessStartInfo 개체에서 UseShellExecute가 true
로 설정된 상태에서 Process.Start(ProcessStartInfo)을 호출합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
macOS의 OpenSSL 버전
macOS에서 .NET Core 3.0 이상 런타임은 이제 AesCcm, AesGcm, DSAOpenSsl, ECDiffieHellmanOpenSsl, ECDsaOpenSsl, RSAOpenSsl 및 SafeEvpPKeyHandle 형식에 대해 OpenSSL 1.0.x 버전보다 OpenSSL 1.1.x 버전을 선호합니다.
.NET Core 2.1 런타임은 이제 OpenSSL 1.1.x 버전을 지원하지만 여전히 OpenSSL 1.0.x 버전을 선호합니다.
변경 내용 설명
이전에는 .NET Core 런타임이 macOS에서 OpenSSL과 상호 작용하는 형식에 대해 OpenSSL 1.0.x 버전을 사용했습니다. 최신 OpenSSL 1.0.x 버전인 OpenSSL 1.0.2는 이제 지원되지 않습니다. 지원되는 버전의 OpenSSL에 대해 OpenSSL을 사용하는 형식을 유지하기 위해 .NET Core 3.0 이상 런타임이 이제 macOS에서 최신 버전의 OpenSSL을 사용합니다.
이러한 변경을 통해 macOS에서 .NET Core 런타임에 대한 동작은 다음과 같습니다.
.NET Core 3.0 이상 버전 런타임은 OpenSSL 1.1.x 버전(사용 가능한 경우)을 사용하고 사용 가능한 1.1.x 버전이 없는 경우에만 OpenSSL 1.0.x 버전으로 대체됩니다.
사용자 지정 P/Invokes에 OpenSSL interop 형식을 사용하는 호출자의 경우 SafeEvpPKeyHandle.OpenSslVersion 설명의 지침을 따릅니다. OpenSslVersion 값을 확인하지 않으면 앱의 작동이 중단될 수도 있습니다.
.NET Core 2.1 런타임은 OpenSSL 1.0.x 버전(사용 가능한 경우)을 사용하고 사용 가능한 1.0.x 버전이 없는 경우 OpenSSL 1.1.x 버전으로 대체됩니다.
.NET Core 2.1에 SafeEvpPKeyHandle.OpenSslVersion 속성이 없어 런타임에 신뢰성 있게 OpenSSL 버전을 확인할 수 없기 때문에 2.1 런타임은 이전 버전의 OpenSSL을 선호합니다.
도입된 버전
- .NET Core 2.1.16
- .NET Core 3.0.3
- .NET Core 3.1.2
권장 작업
더 이상 필요하지 않으면 OpenSSL 1.0.2 버전을 제거합니다.
AesCcm, AesGcm, DSAOpenSsl, ECDiffieHellmanOpenSsl, ECDsaOpenSsl, RSAOpenSsl 또는 SafeEvpPKeyHandle 형식을 사용하는 경우 OpenSSL 1.1.x 버전을 설치합니다.
사용자 지정 P/Invokes에 OpenSSL interop 형식을 사용하는 경우 SafeEvpPKeyHandle.OpenSslVersion 설명의 지침을 따릅니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
- System.Security.Cryptography.AesCcm
- System.Security.Cryptography.AesGcm
- System.Security.Cryptography.DSAOpenSsl
- System.Security.Cryptography.ECDiffieHellmanOpenSsl
- System.Security.Cryptography.ECDsaOpenSsl
- System.Security.Cryptography.RSAOpenSsl
- System.Security.Cryptography.SafeEvpPKeyHandle
.NET Core 1.0
FileSystemInfo.Attributes가 throw하는 UnauthorizedAccessException
.NET Core에서 호출자가 파일 특성 값을 설정하려고 하지만 쓰기 권한이 없는 경우 UnauthorizedAccessException이 throw됩니다.
변경 내용 설명
.NET Framework에서 호출자가 FileSystemInfo.Attributes에서 파일 특성 값을 설정하려고 하지만 쓰기 권한이 없는 경우 ArgumentException이 throw됩니다. .NET Core에서는 대신 UnauthorizedAccessException이 throw됩니다. (.NET Core에서 호출자가 잘못된 파일 특성을 설정하려고 시도하는 경우 여전히 ArgumentException이 throw됩니다.)
도입된 버전
1.0
권장 작업
필요에 따라 ArgumentException 대신 또는 추가로 UnauthorizedAccessException을 catch하도록 catch
문을 수정합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
손상된 상태 예외 처리는 지원되지 않음
.NET Core에서 손상된 프로세스 상태 예외 처리는 지원되지 않습니다.
변경 내용 설명
이전에는 관리 코드 예외 처리기(예: C#에서 try-catch 문을 사용하여)가 손상된 프로세스 상태 예외를 catch하고 처리할 수 있었습니다.
.NET Core 1.0부터는 손상된 프로세스 상태 예외를 관리 코드로 처리할 수 없습니다. 공용 언어 런타임에서는 손상된 프로세스 상태 예외를 관리 코드에 제공하지 않습니다.
도입된 버전
1.0
권장 작업
대신 발생하는 상황을 해결하여 손상된 프로세스 상태 예외를 처리할 필요가 없습니다. 손상된 프로세스 상태 예외를 처리해야 하는 경우 예외 처리기를 C 또는 C++ 코드로 작성합니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
- System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute
- legacyCorruptedStateExceptionsPolicy 요소
UriBuilder 속성은 더 이상 앞에 선행 문자를 추가하지 않음
UriBuilder.Fragment는 더 이상 앞에 선행 #
문자를 추가하지 않으며 UriBuilder.Query는 더 이상 앞에 선행 ?
문자를 추가하지 않습니다(해당 문자가 이미 있는 경우).
변경 내용 설명
.NET Framework에서 UriBuilder.Fragment 및 UriBuilder.Query 속성은 항상 저장되는 값 앞에 각각 #
또는 ?
문자를 추가합니다. 이 동작으로 인해 문자열에 이미 이 선행 문자 중 하나가 포함된 경우 저장된 값에 여러 #
또는 ?
문자가 생성될 수 있습니다. 예를 들어 UriBuilder.Fragment 값이 ##main
이 될 수 있습니다.
.NET Core 1.0부터 이 속성은 더 이상 저장된 값 앞에 #
또는 ?
문자를 추가하지 않습니다(해당 문자가 문자열의 시작 부분에 이미 있는 경우).
도입된 버전
1.0
권장 작업
속성 값을 설정할 때 더 이상 이 선행 문자를 명시적으로 제거할 필요가 없습니다. 더 이상 추가할 때마다 선행 #
또는 ?
를 제거할 필요가 없기 때문에 값을 추가할 경우 이 방법이 특히 유용합니다.
예를 들어 다음 코드 조각은 .NET Framework와 .NET Core의 동작 차이를 보여 줍니다.
var builder = new UriBuilder();
builder.Query = "one=1";
builder.Query += "&two=2";
builder.Query += "&three=3";
builder.Query += "&four=4";
Console.WriteLine(builder.Query);
- .NET Framework에서 출력은
????one=1&two=2&three=3&four=4
입니다. - .NET Core에서 출력은
?one=1&two=2&three=3&four=4
입니다.
범주
핵심 .NET 라이브러리
영향을 받는 API
Process.StartInfo는 코드가 시작하지 않은 프로세스에 대해 InvalidOperationException을 throw함
코드가 시작하지 않은 프로세스의 Process.StartInfo 속성을 읽으면 InvalidOperationException이 throw됩니다.
변경 내용 설명
.NET Framework에서는 코드가 시작하지 않은 프로세스의 Process.StartInfo 속성에 액세스하면 더미 ProcessStartInfo 개체가 반환됩니다. 더미 개체는 EnvironmentVariables를 제외하고 모든 속성에 대한 기본값을 포함합니다.
.NET Core 1.0부터 코드가 (Process.Start를 호출하여) 시작하지 않은 프로세스의 Process.StartInfo 속성을 읽는 경우 InvalidOperationException이 throw됩니다.
도입된 버전
1.0
권장 작업
코드가 시작하지 않은 프로세스의 Process.StartInfo 속성에 액세스하지 마세요. 예를 들어 Process.GetProcesses에서 반환하는 프로세스에 대해서는 이 속성을 읽지 마세요.
범주
핵심 .NET 라이브러리
영향을 받는 API
.NET