Program Language

728x90
반응형

 

 

Back-End를 개발하다보면, JSON을 이용해서 웹 서버와 데이터를 자주 주고 받습니다. 

보통 Front-End 영역에서 Javascript를 이용해서 ajax로 Web API를 호출 하곤 하는데요. 이때 데이터 포멧을 JSON을 이용합니다.

그러다 보면, 빈번히 Javascript 객체를 String 으로 변경하였다가, 다시 객체로 변환하는 경우가 발생하는데요.

이를 쉽게 해주는 메소드입니다. 

 


JSON.stringify()

JSON 의 일반적인 용도는 웹 서버와 데이터를 주고 받는 것 입니다. 웹 서버로 데이터를 보낼 때 데이터는 문자열이여야 하며, JSON.stringify()를 사용해서 Javascript 객체를 문자열로 변환 할 수 있습니다.

 

var obj = { name: "John", age: 30, city: "New York" };
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;



//결과값
{"name":"John","age":30,"city":"New York"}

 

 

JSON에서는 날짜 객체가 허용되지 않습니다. JSON.stringify () 함수는 모든 날짜를 문자열로 변환합니다.

 

var obj = { name: "John", today: new Date(), city : "New York" };
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;


//결과값
{"name":"John","today":"2020-01-10T13:29:19.764Z","city":"New York"}

 

 


 

JSON.parse()

JSON 의 일반적인 용도는 웹 서버와 데이터를 주고 받는 것 입니다. 웹 서버로 데이터를 보낼 때 데이터는 문자열이여야 하며, JSON.parse()로 데이터를 구문 분석하며, 데이터가 Javascript 객체로 변환됩니다.

 

var txt = '{"name":"John", "age":30, "city":"New York"}'
var obj = JSON.parse(txt);
document.getElementById("demo").innerHTML = obj.name + ", " + obj.age;



//결과값
John, 30

 

AJAX 요청을 사용하여 서버에서 JSON을 요청할 수 있습니다. 서버의 응답이 JSON 형식으로 작성되는 한 문자열을 JavaScript 객체로 구문 분석 할 수 있습니다.

 

 


 

 

https://www.w3schools.com/js/js_json_stringify.asp

 

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
728x90
반응형

인터페이스와 다형성

인터페이스에 속한 메서드는 모두 가상 메서드에 속한다.

C# 컴파일러가 인터페이스의 메서드를 가상 메서드로 간주하기 때문에 virtual 예약어를 일부러 지정하지 못하게 막고 있다. 인터페이스를 상속받은 자식 클래스에서도 해당 메서드에 override 예약어를 지정하지 못하게 막는다.

virtual/override 예약어를 막는다기보다는 굳이 그럴 필요가 없으니 표시하지 못하게 한다는 표현이 더 어울린다.

인터페이스의 메서드는 가상 메서드이기 때문에 다형성의 특징이 그대로 적용된다.

 


인터페이스를 이용한 콜백

인터페이스에 포함된 메서드는 상속된 클래스에서 반드시 구현한다는 보장이 있다.

이런점을 이용해서 콜백 구현이 가능하다.

 

간단한 예제

간단한 예제를 하나 생성해서, Log를 찍기위해 인터페이스를 이용한 콜백기능을 만들어 보았다.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogicApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Process.ItemProcess itemProcess = new Process.ItemProcess();
            itemProcess.Run();
        }
    }
}

ItemProcess 라는 Class 를 호출하는 부분을 Main 메소드에 넣어줍니다.

대부분의 예제들이 Main 메소드를 이용하지만, 저는 그냥 실행만 시켜주는 호출단만 생성하였습니다. 

 

 

 

Data.Item.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogicApp.Data
{
    public class Item
    {
        public Process.ILogger Logger { get; set; }

        public Item(Process.ILogger logger)
        {
            this.Logger = logger;
        }

        public bool GetList()
        {
            Logger.SetLog();
            return true;
        }
    }
}

Item 객체의 생성자에서는 Class 가 아닌 ILogger 형태의 인터페이스를 받아주어 의존성을 주입해줍니다.

Item 객체를 생성할때 받은 ILogger를 이용해서, 어느 시점에서든 SetLog 메소드를 호출할 수 있는 구조를 만듭니다.

 

 

Process.ItemProcess.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogicApp.Process
{
    public class ItemProcess : ILogger
    {
        public void Run()
        {
            Data.Item item = new Data.Item(this);
            item.GetList();
        }

        public void SetLog()
        {
            Console.WriteLine("ItemProcess.SetLog");
        }
    }
}

Main 메소드에서 가장 먼저 호출되는 부분입니다. 

ItemProcess에 ILogger를 상속받아 인터페이스 메소드를 구현하였으며, Data.Item 클래스 생성시, 자신의 객체를 this로 넘겨줍니다. ILogger 형태의 인터페이스로 생성자가 받아주기 때문에 구현부가 있는 자신을 인자로 넘겨줍니다.

이것이 인터페이스를 이용한 콜백입니다.

 


의존성 주입으로 변경

public class WebLogger : ILogger
{
    public WebLogger()
    {

    }
    public void SetLog()
    {
        Console.WriteLine("A");
    }
}



public interface ILogger
{
    void SetLog();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogicApp.Process
{
    public class ItemProcess
    {
        public void Run()
        {
            Data.Item item = new Data.Item(new WebLogger());
            item.GetList();
        }
    }
}

위와 같이 ILogger를 상속받아 별도의 클래스를 생성하여, Data.Item 클래스 생성시 넘겨주어도 됩니다.

인터페이스를 이용함으로써, ILogger 인터페이스를 상속받아 새로운 구현부가 존재하는 클래스를 넘겨줄수도 있는 형태로도 운영이 가능합니다. 이는 의존성 주입의 일부분으로 보셔도 됩니다.

 


 

콜백을 구현할 때 델리게이트와 인터페이스 중에 적당한 선택 기준이 있을까요? 사실 거의 대부분의 콜백 패턴에 대해 인터페이스를 사용하는 방법이 더 선호된다.

왜냐하면, 델리게이트는 각 메서드마다 정의해야 하는 불편함이 있지만, 인터페이스는 하나의 타입에서 여러 개의 메서드 계약을 담을 수 있기 때문이다.

대신 델리게이트는 "여러 개의 메서드"를 담을 수 있어서 한번의 호출을 통해 다중으로 등록된 콜백 메서드를 호출 할 수 있다는 고유의 장점이 있다.

 

따라서 다중 호출에 대한 필요성만 없다면 인터페이스를 이용해 콜백을 구현하는 것이 더 일반적입니다.

 

 

 

728x90
728x90
반응형

머리속에 기억해두자니, 자주 사용하지는 않고~ 그렇다고 안필요하진 않은! 이 포맷팅!!

먼저 숫자 형식에 대한 포맷팅을 먼저 정리했습니다.

 

 

 

숫자형식 포맷팅을 이용하면 숫자로 이루어진 문자열을 다양한 형태로 출력 할 수 있습니다.

기본적으로 이 포맷팅은 System. String.Format 매서드에 기반하여 적용됩니다. 

 

 

형식지정자

종류

예제코드

출력결과

C / c

통화
Currency

Response.Write(string.Format("{0:C}", 2.5));

₩3

Response.Write(string.Format("{0:C}", -3.5));

-₩4

D / d

10진법
Decimal

Response.Write(string.Format("{0:D}", 00035));

35

E / e

과학적지수
Scientific

Response.Write(string.Format("{0:E}", 342));

3.420000E+02

F / f

고정 소수점
Fixed-point

Response.Write(string.Format("{0:F2}", 35.22));

35.22

Response.Write(string.Format("{0:F0}", 35.22));

35

G / g

일반
General

Response.Write(string.Format("{0:G}", 123456));

123456

N / n

숫자
Number

Response.Write(string.Format("{0:N}", 25000000));

25,000,000.00

P / p

백분율
Percentage

Response.Write(string.Format("{0:P}", .21548));

21.55%

Response.Write(string.Format("{0:P1}", .112345));

11.2%

X / x

16진법
Hexadecimal

Response.Write(string.Format("{0:X}", 250));

FA

Response.Write(string.Format("{0:X}", 0xffff));

FFFF

 

[출처 : MSDN]

 

 


728x90
728x90
반응형

 

 

실무진에서 이벤트 관련한 코딩을 진행하다 보면,

가장 많이 접하게 되는 것이 시간 및 날짜의 차이를 구하는 구문이 아닐까 생각이 든다.

간단하게 ASP.NET 안에서 C# 구문을 이용하여

날짜, 시간, 분, 초의 차이를 구하는 구문을 만들어 보았다.

 

 

 

차이 구하기

 


  1. DateTime StartDate = Convert.ToDateTime("2012-05-07 08:00:00");
  2. DateTime EndDate = Convert.ToDateTime("2012-05-10 10:20:30");
  3.  
  4. TimeSpan dateDiff = EndDate - StartDate;
  5.            
  6. int diffDay = dateDiff.Days;
  7. int diffHour = dateDiff.Hours;
  8. int diffMinute = dateDiff.Minutes;
  9. int diffSecond = dateDiff.Seconds;
  10.  
  11.  
  12. Response.Write("날짜차이 : " + diffDay.ToString() + "일 <br/>");
  13. Response.Write("시간차이 : " + diffHour.ToString() + "시간 <br/>");
  14. Response.Write("분차이 : " + diffMinute.ToString() + "분 <br/>");
  15. Response.Write("초차이 : " + diffSecond.ToString() + "초 <br/>");
  16.  
  17. Response.End();

 

 

 

결과 화면


날짜차이 : 3일
시간차이 : 2시간
분차이 : 20분
초차이 : 30초

 

 

 

위와 같은 결과 화면을 구현할 수 있다.

 

 

 

 

 

 


728x90

+ Recent posts