Add-Type-TypeDefinition이 추가되지 않은 클래스를 조건부로 추가하려면 어떻게 해야 합니까?
다음과 같은 PowerShell 스니펫을 생각해 보십시오.
$csharpString = @"
using System;
public sealed class MyClass
{
public MyClass() { }
public override string ToString() {
return "This is my class. There are many others " +
"like it, but this one is mine.";
}
}
"@
Add-Type -TypeDefinition $csharpString;
$myObject = New-Object MyClass
Write-Host $myObject.ToString();
동일한 AppDomain에서 두 번 이상 실행하면(예: powershell.exe 또는 powershell_ise.exe에서 스크립트를 두 번 실행) 다음 오류가 나타납니다.
Add-Type : Cannot add type. The type name 'MyClass' already exists.
At line:13 char:1
+ Add-Type -TypeDefinition $csharpString;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (MyClass:String) [Add-Type],
Exception
+ FullyQualifiedErrorId :
TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand
콜을 한 번만 호출하도록 Add-Type-TypeDefinition으로 랩핑하려면 어떻게 해야 합니까?
이 기술은 제게 적합합니다.
if (-not ([System.Management.Automation.PSTypeName]'MyClass').Type)
{
Add-Type -TypeDefinition 'public class MyClass { }'
}
- 형식 이름은 따옴표 'MyClass', 대괄호 [MyClass] 또는 둘 다 '[MyClass]'(v3+만)로 묶을 수 있습니다.
- 형식 이름 조회는 대소문자를 구분하지 않습니다.
- 시스템 네임스페이스(예: [System])의 일부가 아닌 경우 유형의 전체 이름을 사용해야 합니다.DateTime]은(는) 'DateTime'을 통해 조회할 수 있지만, [System].반사.Assembly]는 'Assembly')를 통해 조회할 수 없습니다.
- Win8.1, PowerShell v2, v3, v4에서만 테스트했습니다.
PTypeName 클래스는 내부적으로 LanguagePrimitives를 호출합니다.무거운 리프팅을 처리하는 ConvertStringToType() 메서드입니다.성공하면 조회 문자열을 캐시하기 때문에 추가 조회가 더 빠릅니다.
x0n과 Justin D가 언급한 것처럼 내부적으로 예외가 던져지는지 확인하지 못했습니다.
사실, 이것은 필요하지 않습니다.Add-Type은 사용자가 제출한 코드의 캐시를 결과 유형과 함께 유지 관리합니다.동일한 코드로 Add-Type을 두 번 호출하면 코드를 컴파일하는 데 지장이 없고 지난번에 호출한 코드만 반환됩니다.
Add-Type 호출을 두 번 연속 실행하면 이를 확인할 수 있습니다.
위 예제에서 오류 메시지가 나온 이유는 호출 간의 코드를 Add-Type으로 변경했기 때문입니다.위의 솔루션은 이러한 상황에서 이러한 오류를 제거할 수 있지만, 이는 여러분이 생각하는 대로 행동하지 않을 수도 있는 유형에 대한 이전 정의를 사용하고 있다는 것을 의미합니다.
더 좋은 방법이 있습니다.
예외의 비용을 들이지 않고 :
if (-not ("MyClass" -as [type])) {
add-type @"
public class MyClass { }
"@
}
업데이트: 음, 어쨌든 예외를 제외하고 내부적으로 파워셸 신호를 보내는 것으로 보입니다.이것을 하는 나쁜 습관이 있습니다.인터프리터는 SEH를 사용하여 신호를 전송합니다.break
그리고.continue
예를 들어 키워드를 입력합니다.
가장 간단한 방법은 시도/잡기 블록입니다.이 작업에는 두 가지 옵션이 있습니다.
try { [MyClass] | Out-Null } catch { Add-Type -TypeDefinition $csharpString; }
try { Add-Type -TypeDefinition $csharpString; } catch {}
이렇게 하면 예외가 발생하지 않으며 로드된 어셈블리의 수에 따라 약간 느릴 뿐입니다.
[bool]([appdomain]::CurrentDomain.GetAssemblies() | ? { $_.gettypes() -match 'myclass' })
언급URL : https://stackoverflow.com/questions/16552801/how-do-i-conditionally-add-a-class-with-add-type-typedefinition-if-it-isnt-add
'programing' 카테고리의 다른 글
ES6에서 필터링 또는 지도 노드 목록 (0) | 2023.09.21 |
---|---|
Dectrine에 액세스하는 방법 단순 쿼리 "모든 결과 찾기" (0) | 2023.09.21 |
og_type을 변경할 수 없습니다. (0) | 2023.09.21 |
로컬 호스트와 원격 호스트의 VS 코드에 SQL 구문 오류가 있음 (0) | 2023.09.21 |
예상치 못한 쿼리 성공 (0) | 2023.09.16 |