Program Language/C#

728x90
반응형

 

C# 에서 const 와 readonly는 상수형 타입입니다. 보다 자세히 말씀드린다면,

const는 컴파일 타입의 상수이며, readonly는 런타임 상수입니다.

 


const

  • 컴파일 타입의 상수이다. (컴파일 시 const 변수의 값을 가져온다.)
  • 내장자료형 (정수형, 실수형, Enum, String)에 대해서만 사용 할 수 있다.
  • 변수 선언과 동시에 값을 할당 해야 한다.
  • 메모리 할당 위치는 Stack Memory 이다. 단, static 선언을 하면 Heap Memory에 저장 가능하다.

 


 

readonly

  • 런타임 상수이다. (exe 또는 dll을 사용할 때 변수의 값을 가져온다.)
  • 모든 자료형에 사용 할 수 있으며, 생성과 동시에 초기화 할 필요는 없다.
  • 단, 생성자 단계에서 단 1번 할당을 통해 초기화 할 수 있다. 
  • 메모리 할당 위치는 Heap Memory이다.

 


왜 const 보다 readonly가 더 좋은가?

const는 Stack Memory에 저장 되기 때문에 접근이 빠르다는 장점이 있지만, 

const는 컴파일 상수이기 때문에, const 변수 값이 바뀌는 경우 해당 프로젝트 뿐만 아니라 참조 받거나 영향을 받는 프로젝트 모두 재 컴파일을 해야 하는 단점이 있다.

 

반면, readonly는 생성시 선언하지 않아도, 생성자에서 초기화 하여 사용 할 수 있기 때문에 유연하며, 실제 사용하는 단계에서 변수의 값을 가져오는 장점이 존재한다.

 

 

상수값 변경시 재 컴파일을 하지 않고, 사용하는 생성자 단에서 변수에 값을 할당해서 사용 할 수 있기 때문에

const 보다는 readonly의 사용을 좀 더 고려해볼 필요가 있다.

 

 

 

728x90
728x90
반응형

 

개발자마다 각자의 코딩 스타일이 존재합니다. 다수의 개발자들이 모여 팀 단위로 프로젝트를 진행한다면 코딩 컨벤션 정도는 사전에 맞추고 진행하는 것이 도움이 됩니다. 

또한 코딩 스타일에 대한 정형화 역시 사전에 맞추고 진행하면 다른 개발자들이 소스를 봐도 큰 어색함 없이 작업이 가능한 장점이 있습니다. 이를 위해 강제성을 부여해야 한다고 저는 생각하는데요.

이때 VisualStudio의 setting 파일을 이용해서 작업을 진행해도 되지만, 신규 입사자가 생길경우 해당 셋팅작업이 누락되는 경우 강제성을 부여한 코딩 스타일이 어긋나게 됩니다. 

이를 대비하기 위해 프로젝트에 종속 시켜서 코딩 규칙을 정형화하는 것이 좋으며, EditorConfig를 이용하는 방법을 정리했습니다.

 

 


 

EditorConfig 파일 생성

Solution 에 해당 파일을 추가합니다.

진행하고 있는 프로젝트 솔루션에 새파일을 추가하여 줍니다. 이때 템플릿은 editorconfig 파일로 추가 해 줍니다. 

저는 .NET 스타일로 진행하였습니다. 

 

 


 

EditorConfig 파일 설정

해당 파일을 셋팅하는 것에 대해서 다소 어려움이 있으실 수 있지만, 

아래 링크에 각 변수들이 어떠한 역활을 하는지 잘 설명되어 있습니다. 

저는 Visual Studio 2017 에서 작업 하였기 때문에 이에 맞는 규칙으로 설정하였습니다. 

 

 

 

https://docs.microsoft.com/ko-kr/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017

 

EditorConfig에 대한 .NET 코딩 규칙 설정 - Visual Studio

EditorConfig에 대한 .NET 코딩 규칙 설정.NET coding convention settings for EditorConfig 이 문서의 내용 --> EditorConfig 파일을 사용하여 코드베이스에서 일관된 코드 스타일을 정의하고 유지 관리할 수 있습니다.You can define and maintain consistent code style in your codebase with the use of an EditorConfig file

docs.microsoft.com

 

 

 

 

 

 

728x90

[C#] SonarQube - 정적분석

2020. 1. 29. 19:48
728x90
반응형

 

개발을 할때 단순히 기능만 동작하는 코드를 만드는 것뿐만 아니라, 읽기 좋은 코드를 작성하려고

팀내에서 정형화된 코딩 규칙을 이용해 유지보수하기 좋은 코드 등을 만들기 위해 많은 노력을 합니다. 이를 위해 코드 리뷰 등을 통해 동료 개발자들이 직접 검토하는 경우도 있지만 정형화된 패턴에 대해서는 소스 코드를 분석해주는 도구를 이용할 수 있다. 이러한 것을 코드 정적 분석이라고 합니다.

 

몇가지 툴을 찾아본 결과 아래 SonarQube 라는 툴을 사용해보기로 하였습니다.

 

 

https://www.sonarsource.com/

 

Code Quality and Security | Developers First | SonarSource

Products First Our prime focus and dedication is in building great products that have an impact and are loved by their users. Developer-first Offering Our offering is built to first empower developers with code quality & security tooling, and then enable t

www.sonarsource.com

 


 

Visual Studio 설치

1. Visual Studio 설치 시 Market Place를 이용해서 설치 하였습니다. 도구 > 확장 및 업데이트 메뉴를 선택합니다. 

 

 

2.이후 나타나는 창에서 SonarLint 를 검색해 줍니다. 

 

 

3. 자세한 설치 방법은 아래 링크를 이용해 주세요.

https://improveandrepeat.com/2017/12/integrate-sonarqube-with-visual-studio-using-sonarlint/

 

Integrate SonarQube with Visual Studio using SonarLint

If you follow along with the last few posts on SonarQube, you will now have a working installation that continuously monitors the quality of your code. Today we link Visual Studio to SonarQube usin…

improveandrepeat.com

 


 

정적분석 적용 및 역활

SonarLint를 적용시키고, 현재 진행중인 프로젝트에 적용했을때 보여지는 경고 리스트 입니다. 

여러가지가 보여지네요.

SonarLint 에서는 경고를 띄우지만, 내부에서 결정한 코딩 규칙이 있다면, 무시하고 진행하시면 될 것 같습니다. 

 

자세한 내용은 아래 링크를 통해서 어떠한 내용을 분석해 주는지 확인하면 좋을 것 같습니다. 

https://rules.sonarsource.com/csharp

 

Rules explorer

 

rules.sonarsource.com

 

 

 

 

 

 

 

 

 

728x90
728x90
반응형

 

PHP를 이용해서 개발해보신 분들은 아시겠지만, 암호화 방법중에 기본적으로 이용하는 방식이 MD5를 이용해서 암호화 하는 방식입니다.

이번에 PHP로 개발되어 있는 사이트를 .NET Core 3.1 로 변경하는 도중, 비밀번호를 MD5를 이용해서 암호화한 부분이 있어서 C#으로 대체해보았습니다.

 


MD5 클래스

네임스페이스 : System.Security.Cryptography

위 네임스페이스에 정의 되어 있으며, 

MD5 해시 알고리즘의 모든 구현이 상속될 추상 클래스를 나타냅니다.

 

static string GetMd5Hash(MD5 md5Hash, string input)
{
    // Convert the input string to a byte array and compute the hash.
    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

    // Create a new Stringbuilder to collect the bytes
    // and create a string.
    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of the hashed data 
    // and format each one as a hexadecimal string.
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }

    // Return the hexadecimal string.
    return sBuilder.ToString();
}

MSDN에 정의되어 있는 Sample 예제입니다.

위 예제만 이용하면 손쉽게 MD5를 암호화 해서 사용할 수 있습니다.

 

 

static void Main(string[] args)
{
    var mdHash = MD5.Create();
    string password = "1111";
    Console.WriteLine(GetMd5Hash(mdHash, password));
}


// 결과값
b59c67bf196a4758191e42f76670ceba

MD5.Create() 메소드를 이용해서, System.Security.Cryptography.MD5 해시 알고리즘의 기본 구현 인스턴스를 만들어 줄 수 있습니다. 이를 기반으로 지정된 바이트의 Hash값을 계산해서 사용하게 됩니다. 

 

 


자세한 내용은 아래 MSDN링크를 확인해주세요.

https://docs.microsoft.com/ko-kr/dotnet/api/system.security.cryptography.md5?view=netframework-4.8
728x90
728x90
반응형

C#을 이용해 개발 중이라면, 간혹 실행중인 코드에 대한 호출자정보를 찾아야 할 경우가 있습니다.

Method 이름, 실행중인 파일, 또는 행 번호와 같은 구체적인 호출자정보 일 수 있습니다.

 

저는 주로 이런한 내용이 필요했던 경우는

실행중인 프로그램내에서 발생한 Log를 남길 경우, 어느 파일, 어느 Method 에서 발생한 오류인지를 남기 위해서 필요했습니다. 좀 더 빠른 파악이 가능하고, 체계화된 프로세스를 이용중이라면 빠른 디버깅이 가능하기 때문입니다. 

이를 위해서 호출자정보를 찾던 도중 .NET Framework 4.5에 추가된 CallerMemberAttribute 에 대해서 알게 되었습니다.

 

 

기존에는 Reflection 을 이용해서 처리 하였지만, Reflection이 관련된 경우 현재 코드에 많은 양의 메타 데이터가 로드 및 처리되어야 하므로 성능이 중요한 문제가 될 수 있다는 글을 다수 발견 하였습니다. 

Microsoft MVP 인 Rick Strahl의 게시물에 따르면, 처리 시간이 약 4배 느려질수 있다고 합니다. (일부의 경우)

https://weblog.west-wind.com/posts/2004/Apr/11/Net-Reflection-and-Performance

 

.Net Reflection and Performance

Reflection often gets a bad rap for being slow. True it's much slower than direct access, but it's important to look at performance in the proper perspective. For many operations Reflection and 'evaluative' access to properties, fields and methods provides

weblog.west-wind.com

 


Reflection 을 이용한 처리

Common.Util.cs

public void GetMethod()
{
    SetLog(System.Reflection.MethodBase.GetCurrentMethod(), "Error xxxxxx")
}
public void SetLog( MethodBase method, string msg )
{
    NPLog.PrintError( $"{method.ReflectedType.FullName}.{method.Name} - {msg}" );
}

// 실행결과
Common.Util.GetMethod() - Error xxxxxxxxxxx

 


StackTrace 를 이용한 처리

Common.Util.cs

public void GetMethod()
{
    SetLog(new StackTrace().GetFrame(1).GetMethod(), "Error xxxxxx");
}
public void SetLog( MethodBase method, string msg )
{
    NPLog.PrintError( $"{method.ReflectedType.FullName}.{method.Name} - {msg}" );
}

// 실행결과
Common.Util.GetMethod() - Error xxxxxxxxxxx

 


CallerMemberAttribute 를 이용한 처리

Common.Util.cs

public void GetMethod()
{
    SetLog("Error xxxxxx");
}
public void SetLog( string message, [CallerFilePath] string filePath = null, 
                                    [CallerMemberName] string method = null, 
                                    [CallerLineNumber] int lineNumber = 0 )
{
    NLog.PrintError( $"{filePath} ({method} line is {lineNumber}) - " + message );
}


// 실행결과
D:\Project\SampleProject\Common\Util.cs (GetMethod()) line is 90 - Error xxxxx

 


속도 차이

 

참조 : http://rion.io/2017/11/18/knowing-when-to-reflect-with-caller-info-attributes/

위 링크를 인용하였지만, 1백만 이상 반복한 결과 이와 같은 속도 차이가 있다고 합니다.

또한 CallerMemberName은 메모리 측면에서 훨씬 더 효율적일뿐만 아니라 다른 두 옵션 중 하나보다 훨씬 빠릅니다.

 

 


추가

CallerMemberAttribute 를 사용하면, 속도면에서는 우수 하지만, Log로 남기고 보여지는 부분에서 약간의 가공을 하여야 보기가 좋습니다. 

간단한 파일 구조를 가지고 있다면 모르겠지만, 조금 세분화된 네임스페이스와 파일 구조를 가지고 있다면, 아래와 같이 가공을 하면 조금더 FilePath를 간략해 해서 볼수 있습니다. 

 

public void SetLog( string message, [CallerFilePath] string filePath = null, 
                                    [CallerMemberName] string method = null, 
                                    [CallerLineNumber] int lineNumber = 0 )
{
    NLog.PrintError( $"{filePath.Substring( filePath.IndexOf( System.Reflection.Assembly.GetExecutingAssembly().GetName().Name ) )} ({method} line is {lineNumber}) - " + message );
}

Common.Util - Error xxxxxx

 

 

 

728x90

[C#] Enum 값 검사

2019. 12. 26. 22:54
728x90
반응형

코딩을 하다보면, 컨텐츠의 타입을 결정하는 부분을 Enum 을 이용해서 정의하는 편입니다.

DB에 저장된 데이터 및 기획데이터들과 유효성을 체크해야 하는 부분이 존재하는데요.

이때 검사를 유용하게 하는 방법을 정리하였습니다.

 

 

현재 저희 프로젝트에서 사용하고 있는 각 스테이지의 승리여부를 결정하는 Enum 값 입니다.

/// <summary>
/// 스테이지 승리여부
/// </summary>
public enum STAGE_WIN_TYPE
{
    /// <summary>
    /// 승리
    /// </summary>
    WIN = 0,
    /// <summary>
    /// 패배
    /// </summary>
    LOSE = 1,
    /// <summary>
    /// 비김
    /// </summary>
    DRAW = 2,
    /// <summary>
    /// 포기
    /// </summary>
    GIVEUP = 3,
}

 

 

해당 Enum 값을 이용해서, 데이터의 유효성을 체크 하는 부분에 IsDefined Method를 이용하면 간편하게 값의 유무를 체크 할 수 있습니다.

if ( Enum.IsDefined( typeof( STAGE_WIN_TYPE ), data.Type ) == false )
{
    return false;
}

 

728x90

+ Recent posts