out 매개 변수 한정자를 이용하면 참조를 통해 인수를 전달하고 해당 값을 넘겨 받을 수 있다.

 

이전 버전에서는 out을 사용하기 전에 넘겨줄 변수를 미리 정의했었어야 했는데, C# 7.0버전 부터 인수로 전달되는 위치에 변수를 선언할 수 있게 됐다.

 

void Foo()
{
  // 타입을 명시하지 않고 var키워드도 사용가능하다.
  int.TryParse("1", out var i);
}
 

out 키워드로 여러 값을 반환받는 경우가 있는데 특정 값이 필요 없는 경우에 아래와 같이 선언할 수 있다.

 

Foo(out var x1, out var x2, out _);
 
반응형

'Workspace > C#' 카테고리의 다른 글

[C# 7.0] 로컬 함수  (1) 2023.04.17
[C#] partial 키워드  (0) 2023.04.06
[C#] new 한정자  (0) 2023.04.06
[C# 7] Tuple  (0) 2023.04.06
[C#] .NET Framework에 대응되는 버전  (1) 2023.04.06

C# 7.0에 로컬 함수란 것이 추가되었다.

메서드 내의 메서드로 중첩된 형식이다.

 

로컬 함수를 포함하는 메서드내에서만 호출할 수 있기 때문에

실수로 메서드를 호출되는 상황 등을 방지할 수 있고, 코드의 의도를 명확하게 한다.

 

| 사용방법

 

public class Foo
{
  public void DoBar() {
    int foobar = 1;
    DoTask().Forget();    

    // 로컬 함수
    async UniTask DoTask() {
      foobar++;
      await DoSome(foobar);
    }
  }
}
 

위와 같이 메서드 내에 정의하고 보통의 메서드처럼 호출해서 사용하면 된다.

 

| 제약

 

로컬 함수는 아래에서 선언하고 호출할 수 있다.

 

  • 메서드, 반복기 메서드 / 비동기 메서드
  • 생성자
  • 속성 접근자
  • 이벤트 접근자
  • 무명 메서드
  • 람다 식
  • 종료자(소멸자)
  • 다른 로컬 함수

 

그리고 아래의 한정자를 사용할 수 있다.

 

  • async
  • unsafe
  • static (단, 지역 변수나 인스턴스 상태를 캡처할 수 없음)
  • extern

 

로컬 함수 캡처나, Action, Func, delegate 형식에 대입도 되는 것 같다.

자세한 내용은 공식문서를 참고하시라.

 

| 참고

 

 

 

반응형

'Workspace > C#' 카테고리의 다른 글

[C# 7.0] 출력(out) 변수 선언  (0) 2023.04.17
[C#] partial 키워드  (0) 2023.04.06
[C#] new 한정자  (0) 2023.04.06
[C# 7] Tuple  (0) 2023.04.06
[C#] .NET Framework에 대응되는 버전  (1) 2023.04.06

| 개요

 

무료 .NET 디컴파일러 dotPeek의 주요 기능과 사용 방법에 대해 이해

 

| dotPeek이란?

 

dotPeek은 JetBrains에서 개발한 무료 .NET 디컴파일러입니다. 

.NET으로 작성된 어셈블리나 실행파일에서 C# 코드를 추출하고 디버깅할 수 있습니다.

 

| dotPeek 주요 기능

 

  • .NET 어셈블리 디컴파일링
  • 코드 분석 및 탐색
  • 심볼 서버 지원
  • 기존 Visual Studio 단축키 지원
  • C# 최신 언어 기능 지원
  • 코드 스타일 및 레이아웃 설정

 

| dotPeek 설치 방법

 

  • dotPeek 사이트에서 dotPeek 다운로드
  • 약관 동의

  • 인스톨 실행

| 디컴파일 및 어셈블리 브라우징 방법

 

dotPeek 설치 후 초기 실행 화면은 아래와 같습니다.

Assembly Explorer 윈도우에 .NET으로 컴파일한 dll 또는 exe파일을 드래그 & 드랍으로 추가할 수 있습니다.

Newtonsoft.Json.dll을 열어본 모습

il2cpp로 빌드된 경우나, 난독화 된 경우 dotPeek으로 분석하는 데엔 한계가 있습니다.

 

| 프로젝트 추출 방법

  • 임포트한 프로젝트 우클릭
  • Export to Project 클릭
  • 추출 경로 및 옵션 설정

어셈블리 내 모든 C# 코드와 솔루션 및 프로젝트 파일까지도 생성할 수 있습니다.

 

| 유니티로 제작된 게임 코드 보기

  • 스팀 > 유니티로 제작된 게임 우클릭 > 속성

  • 로컬 파일 탭 > 찾아보기 버튼

  • <게임명>_Data 폴더 > Managed > Assembly-CSharp.dll (혹은 그 외 다른 dll)

 

| 결론

 

dotPeek을 통해서 간단한 과정을 거쳐, 실행파일을 디컴파일을 하거나 어셈블리를 브라우징할 수 있었습니다.

이를 통해 다른 사람들의 코드를 이해하거나 이전 버전의 코드를 복원(유실된 경우)하는 등의 다양한 용도로 사용할 수 있을 거 같습니다.

 

Visual Studio의 단축키 및 기능(예) 정의로 이동, 모든 참조 찾기 등)들을 많이 지원하고 있어서

Visual Studio 혹은 Visual Studio Code 등의 IDE를 사용해본 유저라면 직관적으로 이해하고 쉽게 사용할 수 있습니다.

반응형

partial 한정자는 클래스, 구조체, 인터페이스 등을 둘 이상의 분할된 형태로 정의할 수 있는 키워드다. (부분 클래스, 부분 메서드 등으로 불림) (C# 2.0) 분할된 파일들은 컴파일될 때 결합된다.

 

다음은 partial이 권장되는 몇 가지 상황이다.

 

  • 대규모 프로젝트에서 한 클래스에 대해 여러 프로그래머가 동시에 작업할 경우
  • 스크립트 일부를 자동 생성하는 경우 (예) Windows Forms)

 

| partial 키워드 사용방법

 

// Foo.cs
public partial class Foo
{
    public void DoWork()
    {
    }
}

// Foo.Generated.cs
public partial class Foo
{
    public void Bar()
    {
    }
}
 

class, struct, interface앞에 partial 한정자를 기입하면 된다.

단, public, private 등과 같은 액세스 한정자로 지정해야한다. (class, struct, interface, 멤버 등 모든 경우)

 

| 병합 범위

 

class, struct 등의 부분이 absract, sealed로 선언되면 전체 형식이 absract, sealed로 간주된다.

 

이외에도 병합되는 것들

  • XML 주석 (예) summary, returns)
  • 인터페이스
  • 제너릭 형식 매개 변수 Attrbute
  • 클래스 Attribute
  • 멤버
[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }

>> 

[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
 
  • Attribute 병합 예
partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }

>>

class Earth : Planet, IRotate, IRevolve { }
 
  • 인터페이스 병합 예

 

| 제한사항

 

  • partial로 정의된 형식의 모든 부분이 partial로 정의되어야 함
public partial class A { }
//public class A { }  // Error, must also be marked partial
 
  • 동일한 어셈블리에 동일한 모듈(exe 혹은 dll)에 정의해야 함
  • 아래 키워드를 다르게 설정할 경우 충돌

 

  1. public, private, protected, internal
  2. abstarct, sealead
  3. new 한정자
  4. 제너릭 제약 조건

 

| 부분 메서드

 

C# 3.0 사양에 추가된 내용으로 메서드 또한 부분 형식으로 정의가 가능하다.

partial 키워드 자체가 우선순위 없이 병합되는 형식이기 때문에

부분 메서드의 경우엔 정의 부분과 구현 부분으로 나뉜다.

// Definition in file1.cs
partial void OnNameChanged();

// Implementation in file2.cs
partial void OnNameChanged()
{
  // method body
}
 

하나 특이한 점은 구현되지 않는 부분 메서드의 경우(정의 부분만 있는) 컴파일러가 메서드 정의, 호출 코드를 삭제한다.

 

한정자나 제한 상황에 따라 구현을 포함해야하는 지 여부가 갈린다.

아래 제한 사항을 따른다면 구현을 포함하지 않아도 된다.

 

  • 액세스 한정자가 없는 경우 (디폴트: private)
  • void를 반환
  • out 매개 변수 없는 경우
  • 한정자 virtual, override, sealed, new, extern가 없는 경우

 

위 제한 사항을 따르지 않는 경우엔 (예) public virtual partial void) 구현을 제공해야만 한다.

 

| 부분 메서드 제한사항

 

  • unsafe, static 한정자를 사용할 수 없다.

 

| 참고

 

 

반응형

'Workspace > C#' 카테고리의 다른 글

[C# 7.0] 출력(out) 변수 선언  (0) 2023.04.17
[C# 7.0] 로컬 함수  (1) 2023.04.17
[C#] new 한정자  (0) 2023.04.06
[C# 7] Tuple  (0) 2023.04.06
[C#] .NET Framework에 대응되는 버전  (1) 2023.04.06

 

new는 인스턴스를 생성하는 데 쓰이는 경우가 제일 익숙하리라 생각이 된다.

하지만 new 키워드는 생각보다 다양한 역할을 한다.

 

 

이 글에선 new 한정자에 대해 알아보자.

 

| new 한정자를 알게되는 경위

 

The keyword new is required on 'DerivedC.x' because it hides inherited member 'BaseC.x'.
 

보통 파생된 클래스에서 같은 이름의 멤버를 지정하다 알게 될 확률 58,000%다.

물론 new 한정자가 없어도 경고 메시지를 낼 뿐, 기본 클래스의 멤버를 숨기는 것으로 동작한다.

 

| new 한정자 사용법

 

public class BaseC
{
    public int x;
    public void Invoke() { }
}
public class DerivedC : BaseC
{
    new public void Invoke() { }
}
 

 

숨기고 싶은 멤버 (property, field, method, indexer, const) 앞에 new 한정자를 기입해주면 된다.

한 가지 유의사항이 있다면, override 한정자와는 동시에 사용할 수 없다.

 

| 참고

 

 

반응형

'Workspace > C#' 카테고리의 다른 글

[C# 7.0] 출력(out) 변수 선언  (0) 2023.04.17
[C# 7.0] 로컬 함수  (1) 2023.04.17
[C#] partial 키워드  (0) 2023.04.06
[C# 7] Tuple  (0) 2023.04.06
[C#] .NET Framework에 대응되는 버전  (1) 2023.04.06

C# 7버젼대 부터 Tuple 형식으로 메서드 결과를 반환할 수 있다.

(int min, int max) FindMinMax(int[] input)
{
    if (input is null || input.Length == 0)
    {
        throw new ArgumentException("Cannot find minimum and maximum of a null or empty array.");
    }

    var min = int.MaxValue;
    var max = int.MinValue;
    foreach (var i in input)
    {
        if (i < min)
            min = i;        
        if (i > max)
            max = i;        
    }
    return (min, max);
}
 

 

메서드 반환뿐만 아니라 Linq, 쿼리, 제너릭에서도 모두 사용 가능하다.

특별히 이름을 지정해주지 않으면 필드는 Item1, Item2... 와 같이 네이밍된다.

이때 Tuple은 값형식이다.

| 필드 이름 지정

 

아래와 같이 튜플 초기화나 정의 부분에서 필드의 이름을 명시적으로 지정할 수 있다.

var t = (Sum: 4.5, Count: 3);
Console.WriteLine($"Sum of {t.Count} elements is {t.Sum}.");

(double Sum, int Count) d = (4.5, 3);
Console.WriteLine($"Sum of {d.Count} elements is {d.Sum}.");
 

| Tuple 참조형식과의 비교

 
 
구분
형식
변경가능 여부
데이터 멤버
System.ValueTuple
가능
필드
System.Tuple
참조
불가능
속성 (get)

 

| 무명형식과의 비교

 
 
이름
액세스 한정자
형식
커스텀 멤버 이름
분해 지원
식 트리 지원
무명 형식
internal
class
O
X
O
Tuple
public
class
X
X
O
Value Tuple
public
struct
O
O
X

Tuple 문서를 읽다가 무명 형식에 대해서도 보게 되었는데, 위 표를 보고 비교해서 알맞은 상황에 사용하면 될 것 같다.

 
// 간단한 사용법
var foo = new { Formatted = $"{date:MMM dd, yyyy hh:mm zzz}", date.Ticks };

// 컴파일러에서 아래와 같이 생성된다.
internal sealed class f__AnonymousType0
{
    public string Formatted { get; }
    public long Ticks { get; }

    public f__AnonymousType0(string formatted, long ticks)
    {
        Formatted = formatted;
        Ticks = ticks;
    }
}
 

 

| 마치며

 

Tuple로 인해 데이터 요소를 간결하게 구문화하는 것이 가능해졌다. Tuple은 단순히 그룹화 하는데 그치지 않고 할당 및 분해, 비교 연산자 등 다양한 기능을 제공하는데, 암시적으로 형변환되거나 컴파일러가 유추하는 부분이 많아서 유의해서 사용할 필요가 있다.

 

| 참고

 
반응형

'Workspace > C#' 카테고리의 다른 글

[C# 7.0] 출력(out) 변수 선언  (0) 2023.04.17
[C# 7.0] 로컬 함수  (1) 2023.04.17
[C#] partial 키워드  (0) 2023.04.06
[C#] new 한정자  (0) 2023.04.06
[C#] .NET Framework에 대응되는 버전  (1) 2023.04.06

C#은 .NET Framework 버전 및 Visual Studio 버전과 밀접한 관련이 있으며, 다음 도표에서 각 버젼별 연관성을 살펴 볼 수 있다.

 
.NET 버전
C# 버전
Visual Studio
.NET 1.0
C# 1.0
Visual Studio .NET
.NET 1.1
C# 1.1
Visual Studio .NET 2003
.NET 2.0
C# 2.0
Visual Studio 2005
.NET 3.0
C# 2.0
Visual Studio 2005 Extensions
.NET 3.5
C# 3.0
Visual Studio 2008
.NET 4.0
C# 4.0
Visual Studio 2010
.NET 4.5
C# 5.0
Visual Studio 2012
Visual Studio 2013
.NET 4.6
C# 6.0
Visual Studio 2015
.NET 4.6.2
C# 7.0
Visual Studio 2017
.NET 4.7
C# 7.1
Visual Studio 2017 Update 15.3
.NET 4.7.1
C# 7.2
Visual Studio 2017 Update 15.5
.NET 4.7.2
C# 7.3
Visual Studio 2017 Update 15.7
.NET Core 3.0
C# 8.0
Visual Studio 2019 Update 16.3 + .NET Core 3.0
.NET 5.0
C# 9.0
Visual Studio 2019
.NET 6.0
C# 10.0
Visual Studio 2022
.NET 7.0
C# 11.0
Visual Studio 2022 Update 17.4 이상
  • Visual Studio 2010은 .NET 4.0 뿐만 아니라 .NET 2.0, .NET 3.0, .NET 3.5도 지원한다.
  • Visual Studio 2008은 .NET 3.5 뿐만 아니라 .NET 2.0, .NET 3.0도 지원한다.
  • C# 7.1, C# 7.2, C# 7.3은 Minor 버전으로 자동으로 Enable되지 않으며, VS에서 C# 프로젝트 속성창 => Build 탭 => Advanced 버튼 => Language Version 콤보박스에서 해당 버전을 선택해야 한다.
  • C# 8.0을 사용하기 위해서는 VS 2019를 Update 16.3 이상으로 업데이트하고 .NET Core 3.0 을 설치한 후 사용한다. C# 8.0은 .NET Framework 4.8에서 사용할 수 없다.
  • C# 10을 사용하기 위해서는 VS 2022/.NET 6를 설치한다. C# 10은 .NET 6에 포함되어 있다.
  • C# 11을 사용하기 위해서는 VS 2022 Update 17.4 이상과 .NET 7을 설치한다. C# 11은 .NET 7에 포함되어 있다.
 
Target
버전
C# 언어 버전 기본값
.NET Core
3.x
C# 8.0
.NET Core
2.x
C# 7.3
.NET Standard
2.1
C# 8.0
.NET Standard
2.0
C# 7.3
.NET Standard
1.x
C# 7.3

 

| 참고

 

 

반응형

'Workspace > C#' 카테고리의 다른 글

[C# 7.0] 출력(out) 변수 선언  (0) 2023.04.17
[C# 7.0] 로컬 함수  (1) 2023.04.17
[C#] partial 키워드  (0) 2023.04.06
[C#] new 한정자  (0) 2023.04.06
[C# 7] Tuple  (0) 2023.04.06

앱센터란 어플리케이션 빌드, 테스트 및 배포 솔루션으로 분석 및 진단 서비스도 제공되어 상태나 사용량을 모니터링할 수 있다.

앱센터는 전신격이라고 할 수 있는 하키앱이란 서비스를 기능을 확장/개편하면서 Visual Stuido App Center라는 새 간판을 달았다.

2014년 하키앱이 MS에 인수되고, 2019년 11월 앱센터로 전환되었다.
 

홈페이지 개요를 보면 빌드에서 배포, 테스트까지 할 수 있는 거 같은데

필자는 젠킨스와 애증의 관계로 빌드는 젠킨스, 빌드 배포는 앱센터로 하기로 한다.

 

| 회원가입

 
 

App Center

 

appcenter.ms

우선 위 홈페이지로 가서 회원가입을 해준다.

 

| 조직 설정

빈 화면이 우리를 반겨주니 어서 앱 혹은 조직을 추가해보자.

우측 상단 Add new 버튼을 클릭하여 [앱] 혹은 [조직]을 추가하자.

 

※별도의 조직 없이 앱을 추가할 수 도 있다.

(조직과 앱에 대한 자세한 내용은 따로 다뤄보도록 한다.)

 

| 앱 설정

  • 앱명과 아이콘, Release 타입, OS 그리고 플랫폼을 입력
  • Add new app 버튼 클릭
제안된 릴리즈 타입, 원하는 것이 없다면 Custom을 이용

앱 설정까지 끝냈다면 기반은 완성이다.

이제 빌드 결과물 업로드, 배포 그룹 설정, 릴리즈 버전 관리 등의 작업이 가능하다.

 

| API 설정방법

이제 생성된 [조직] 혹은 [앱]에 젠킨스를 통해서 업로드하는 설정을 해볼 것이다.

우선 선행되어야하는 것이 API 토큰을 생성하는 것이다.

 

  1. API 토큰 생성
 
  • 생성된 앱 > Settings > App API tokens > New API tokens 버튼 클릭
토큰은 다시 확인할 수 없으니 반드시 백업이 필요하다.

대충 토큰 명을 입력하고, 권한을 설정하고 토큰을 Add new API token버튼 클릭하면 아래와 같은 팝업이 뜬다.

 

 

| 젠킨스 설정

1. App Center 플러그인 설치

Manage Jenkins Manage Plugins > Available plugins > App center 입력 > 플러그인 설치

 

2. 잡 설정

  • Post-build Actions에 Upload app to AppCenter 추가
 
  • 추가된 빌드 액션에 아래 값들을 설정 (필수 입력 값: API Token, Owner Name, App Name, Path To App, Distribution Groups, 나머지는 선택적 입력 값)
 
 
 
변수명
비고
API Token
위에서 발급한 API Token
40자리
Owner Name
유저명
생성한 앱의 URL 참조
App Name
앱명
생성한 앱의 URL 참조
Path To App
빌드파일의 상대 경로
 
Distribution Groups
배포 그룹
그룹명 혹은 멤버명
(콤마(,)로 추가) ex) Collaborators, QA
Mandatory Update
강제업데이트 여부
 
Notify Testers
알림 여부
 
Build Version
빌드 버전
 
Path To Debug Symbols
디버그용 심볼 경로
 
Branch Name
깃 브랜치명
origin/master or $GIT_BRANCH
Commit Hash
깃 커밋 해쉬값
$GIT_COMMIT
Release Notes
릴리즈 노트
5000자 제한
Release Notes From A File
릴리즈 노트 파일 경로
path/${NOTES}.md

 

3. URL 설정

Owner Name, App Name은 각각 생성한 앱 URL을 참조하여 입력한다.

조직내 앱을 추가한 경우)

https://appcenter.ms/orgs/${OwnerName}/apps/${AppName}

 

#조직 없이 앱을 생성한 경우)

https://appcenter.ms/users/${OwnerName}/apps/${AppName}

 

반응형

+ Recent posts