반응형

C#에서 객체를 초기화하는 방법은 여러가지가 있습니다. 가장 기본적인 방법은 객체를 생성한 후 각 프로퍼티를 따로 지정하는 것입니다.

class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
}
 
Car myCar = new Car();
myCar.Make = "Toyota";
myCar.Model = "Camry";
myCar.Year = 2019;

또 다른 방법으로는 생성자를 통한 객체 초기화가 있습니다. 생성자를 통해 객체를 생성할 때 필요한 프로퍼티 값들을 매개변수로 전달할 수 있습니다.

class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
 
    public Car(string make, string model, int year)
    {
        Make = make;
        Model = model;
        Year = year;
    }
}
 
Car myCar = new Car("Toyota", "Camry", 2019);
 

마지막으로, C#에서는 Object Initializer 문법을 사용하여 객체를 초기화할 수 있습니다. 이 문법을 사용하면 객체를 생성할 때 필요한 프로퍼티 값들을 직접 지정할 수 있습니다.

class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
}
 
Car myCar = new Car
{
    Make = "Toyota",
    Model = "Camry",
    Year = 2019
};
 

위의 코드에서는 new Car 이후에 각 프로퍼티의 값을 직접 지정하여 객체를 초기화하고 있습니다. 단, 값을 지정할 수 있는 것은 public 속성(property)만 가능 합니다.

위에서 언급한 3가지 방법 중 가장 편리한 방법은 Object Initializer 문법이며, 이 문법을 사용하면 간결하고 직관적인 코드를 작성할 수 있습니다.

반응형
반응형

.Net 환경에서 로깅 처리를 할 수 있는 log4net 사용법 입니다.

1.Visual Studio의 NuGet 패키지 관리에서 log4net을 검색 하여 설치 합니다.

2. 설치가 완료되면 참조에 log4net이 추가 됩니다.

3. 구성 파일을 신규로 작성하여 추가 합니다.

<?xml version="1.0" encoding="utf-8"?>

<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="RollingFileAppender" />
  </root>
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <!--<file type="log4net.Util.PatternString" value="log-%property{processid}-%date{yyyy-MM-dd}.txt" />-->
    <file value="Log\common.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
    </layout>
  </appender>
</log4net>

구성파일에 대한 자세한 작성법은 여기를 참조 합니다.

4. 구성파일은 프로그램 배포시 별도의 파일로 존재할 수도 있지만 여기서는 어셈블리에 포함 시키기 위하여 속성창에서 빌드 작업을 '포함 리소스'로 지정 합니다.

5. 이제 로그를 남기기 원하는 곳에서 실제로 로그 처리를 합니다.

namespace log4net_test
{
    internal class Program
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            var assembly = typeof(Program).Assembly;
            using (var stream = assembly.GetManifestResourceStream("log4net_test.config.log4net.config"))
            {
                log4net.Config.XmlConfigurator.Configure(stream);
            }

            log.Info("Application started");
            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
            log.Info("Application ended");
        }
    }
}

여기서 GetManifestResourceStream() 메소드의 인자값으로 포함 리소스로된 구성파일을 전달 합니다. 예제의 경우 config 폴더를 만들어서 그 아래에 구성파일을 두었기 때문에 폴더명을 '.' 을 이용하여 위와 같이 namespace와 파일명 사이에 넣어 줘야 합니다.

빌드 후 프로그램을 실행 시켜보면 구성파일에서 지정한 로그 파일인 Log\common_log 가 생성되고 로그가 남게 됩니다.

 

반응형
반응형

closure(클로저)는 함수와 그 함수가 선언된 스코프(scope) 사이의 관계를 말합니다. closure는 함수가 정의될 때의 환경을 기억하고, 그 환경에서 정의된 변수에 접근할 수 있는 기능을 제공합니다.

JavaScript의 함수는 first-class citizen이므로, 변수에 할당하거나 다른 함수의 인자로 전달할 수 있습니다. closure는 이러한 특징을 이용하여 함수를 반환하거나 함수를 전달할 때, 함수가 정의된 스코프에서 선언된 변수에 접근할 수 있는 것을 가능하게 합니다.

이는 외부 함수가 종료되어도 내부 함수가 참조하는 변수들이 유지되어 외부 함수의 변수에 접근할 수 있게 합니다.

function outerFunction(x) {
  return function innerFunction(y) {
    return x + y;
  };
}

const add5 = outerFunction(5);
console.log(add5(3)); // 8

위의 코드에서 outerFunction은 x 값을 매개변수로 받습니다. 그리고 innerFunction 함수를 반환합니다. innerFunction 함수는 y 값을 매개변수로 받습니다.

그리고 add5 변수에 outerFunction(5)의 결과를 할당합니다. 이 결과는 innerFunction 함수입니다. 그러므로 add5(3)을 실행하면 innerFunction 함수가 실행되고 x+y의 결과인 8이 출력됩니다.

아래의 코드에서는 createCounter 함수가 closure를 생성합니다.

function createCounter() {
  let count = 0;
  return function() {
    return ++count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

createCounter 함수가 반환하는 함수는 count 변수에 접근할 수 있어서, counter 변수에 저장된 함수를 호출할 때마다 count 값이 1씩 증가합니다.

closure는 코드의 캡슐화(encapsulation)에 많이 사용됩니다. 내부 함수가 외부 함수의 변수에 접근할 수 있기 때문에, 외부 함수의 변수를 숨기고 내부 함수만을 통해서 접근할 수 있는 기능을 구현할 수 있습니다.
위의 소스에서 count 변수는 closure를 통해 은닉화 되었습니다.

closure는 애플리케이션의 구조화와 모듈화에 큰 도움이 될 수 있습니다. 예를 들어, 아래의 코드에서는 private 변수를 통해서 외부에서 접근할 수 없는 값을 저장할 수 있습니다.

function Person(name) {
  let privateName = name;
  
  return {
    getName: function() {
      return privateName;
    },
    setName: function(newName) {
      privateName = newName;
    }
  };
}

const person = Person("John");
console.log(person.getName()); // John
person.setName("Jane");
console.log(person.getName()); // Jane

closure를 사용하면, 객체의 내부 상태를 외부에서 변경할 수 없게 할 수 있습니다. 그리고 내부에서만 접근할 수 있는 메소드를 구현할 수 있어서, 애플리케이션의 코드를 깔끔하게 유지할 수 있습니다.

closure의 장단점

장점

  1. 변수의 유지

closure는 외부 함수의 변수를 저장하여 외부 함수가 종료된 후에도 변수를 사용할 수 있습니다. 이는 메모리 효율성을 높여줍니다.

  2. 은닉성

closure를 사용하면 외부 함수의 변수와 내부 함수를 숨길 수 있어 변수의 접근을 제어할 수 있습니다.

  3. 단일 책임 원칙

closure는 함수의 역할을 구분하여 각각의 역할이 담당하는 변수와 함수를 분리할 수 있습니다. 이는 단일 책임 원칙을 준수하는 코드를 작성할 수 있게 해줍니다.

단점

  1. 메모리 낭비

closure를 사용하면 외부 함수가 종료된 후에도 내부 함수가 참조하는 변수를 메모리에 저장해야 하므로 메모리 낭비가 생길 수 있습니다.

  2. 코드 가독성

closure를 많이 사용하면 코드가 복잡해지고 이해하기 어렵습니다. 따라서 클로저를 사용할 때에는 적절한 주석과 코드 구조를 갖추어야 합니다.

반응형
반응형

구독하고 있는 chris@gomakethings.com의 메일링 리스트로 온 내용을 번역했습니다.

Array.prototype.find() 메서드는 배열에서 콜백 함수로 전달한 테스트와 일치하는 첫 번째 항목을 찾습니다. 콜백은 배열의 현재 항목을 참조하는 참조 변수를 위한 인수를 제공합니다.

다음은 샌드위치 배열에서 참치를 찾는 간단한 예입니다.

let sandwiches = ['turkey', 'chicken salad', 'tuna', 'pb&j', 'egg salad'];

let tuna = sandwiches.find(function (sandwich) {
	return sandwich === 'tuna';
});

console.log(tuna); // logs "tuna"

항목을 찾지 못하면 undefined를 반환합니다.

let hamburger = sandwiches.find(function (sandwich) {
	return sandwich === 'hamburger';
});

console.log(hamburger); // logs undefined

Array.prototype.find() 메서드가 진짜 잘 작동하는 곳은 복잡한 배열입니다.

예를 들어, todo 객체가 포함된 배열을 가지는 JSON 파일을 반환하는 API가 있다고 가정해봅시다.

let todos = [
	{
		item: 'Wash the dog',
		added: 20180322,
		completed: false
	},
	{
		item: 'Plan surprise party for Bailey',
		added: 20180314,
		completed: false
	},
	{
		item: 'Go see Black Panther',
		added: 20180312,
		completed: true
	},
	{
		item: 'Launch a podcast',
		added: 20180305,
		completed: false
	}
];

어떻게 하면 'Go see Black Panther' 아이템이 언제 추가됐는지, 완료됐는지 확인할 수 있을까?

Array.prototype.find() 메서드가 없을 경우, 각각의 할 일을 반복하여 아이템을 확인하고, 일치하는 결과를 저장하고, 루프을 종료해야 합니다.

let item;
for (let todo of todos) {
	if (todo.item === 'Go see Black Panther') {
		item = todo;
		break;
	}
}

Array.prototype.find() 메서드를 사용할 경우, todo.item 속성이 'Go see Black Panther' 인 것을 확인하면 됩니다.

let item = todos.find(function (todo) {
	return todo.item === 'Go see Black Panther';
});
반응형

+ Recent posts