2009-04-11 10 views

답변

189

개체 이니셜 라이저는 객체를 사용할 때 뭔가의 건설을 단순화하기 위해, C# 3에 추가했다.

생성자는 0 개 이상의 매개 변수를 제공, 실행 및 호출 방법은 생성 된 객체에 대한 핸들을 얻을 수 전에 객체 를 생성하고 초기화하는 데 사용됩니다.예를 들어이 경우

MyObject myObjectInstance = new MyObject(param1, param2); 

, MyObject의 생성자는 값 param1param2으로 실행됩니다. 이것들은 모두 메모리에 새로운 MyObject을 생성하는 데 사용됩니다. 생성 된 객체 (해당 매개 변수를 사용하여 설정 됨)가 반환되고 myObjectInstance으로 설정됩니다.

일반적으로 개체를 완전하게 설정하는 데 필요한 매개 변수가 필요한 생성자를 사용하면 잘못된 상태로 개체를 만들 수 없다는 것이 좋습니다.

그러나 종종 설정할 수있는 "추가"속성이 있지만 필수는 아닙니다. 이것은 오버로드 된 생성자를 통해 처리 될 수 있지만 대다수의 상황에서 반드시 유용하지는 않은 많은 생성자를 갖게됩니다. 이니셜은 당신이이 구성되어있어 한 후 개체 의 속성 또는 필드를 설정할 수 있습니다 개체를하지만, 전에 당신은 아무것도에 의해 사용할 수 있습니다 -

이것은 초기화 객체에 연결됩니다. 예를 들어 : 그러나

MyObject myObjectInstance = new MyObject(param1, param2); 
myObjectInstance.MyProperty = someUsefulValue; 

그 이후, 멀티 스레드 도움이 될 수있는 객체 이니셜의 자성을 환경 에 :이 작업을 수행하는 것처럼

MyObject myObjectInstance = new MyObject(param1, param2) 
{ 
    MyProperty = someUsefulValue 
}; 

이 거의 같은 동작합니다 객체가 완전히 초기화되지 않은 상태가되는 것을 방지합니다 (자세한 내용은 this answer 참조). 의도 한 것처럼 null이거나 초기화되었습니다.

또한 개체 이니셜 라이저는 (특히 여러 값을 설정할 때) 읽기가 더 쉽습니다. 따라서 많은 오버로드가 해당 클래스의 API를 복잡하게 만들 필요없이 생성자에서 많은 오버로드와 동일한 이점을 얻을 수 있습니다. 당신이

Person p = new Person { Name = "a", Age = 23 }; 

을 수행 할 때

+22

나는 동의하지만, 특히 디버깅 객체 이니셜 라이저가 고통 스러울 수 있다고 덧붙이고 싶습니다. 특히 중첩 된 구조체 인 경우, 객체 이니셜 라이저가 문장 한 줄 (멋지게 형식화 된)으로 간주되기 때문에 중첩 된 구조가 있습니다. – CrnaStena

+0

@ Reed-Copsey 아주 좋은 설명, 개체 이니셜 라이저를 사용하면 성능이 향상 될지 아니면 가독성을 위해서만 사용할까요? – Mahender

+2

@Mahender 사실, 객체 이니셜 라이저를 사용할 때 일반적으로 (매우 작은) 성능 손실이 있습니다. 생성자는보다 효율적으로 작성 될 수 있습니다. –

40

생성자는 지정된 수의 매개 변수를 사용하여 개체를 만들고 초기화하는 형식에 대해 정의 된 메서드입니다.

개체 이니셜 라이저는 생성자 다음에 개체에서 실행되는 코드로, 개체의 모든 필드를 지정된 값으로 간결하게 설정하는 데 사용할 수있는 코드입니다. 이 필드의 설정은 후에 생성자가 호출 된 후 이 발생합니다.

생성자가 개체의 초기 상태를 충분히 설정 한 경우 개체 이니셜 라이저를 사용하지 않고 생성자를 사용합니다. 그러나 객체 이니셜 라이저는 생성자와 함께 사용해야합니다. 구문을 사용하면 초기 개체를 만들기 위해 생성자의 명시 적 또는 암시 적 사용 (VB.Net 및 C#)이 필요합니다. 생성자가 객체를 사용하기에 충분하게 초기화하지 않고 몇 가지 간단한 필드 및/또는 속성 집합을 만들 때 객체 이니셜 라이저를 사용합니다.

+13

"after"노트가 중요합니다. – user8032

4

생성자는 매개 변수를 받아들이고 클래스의 새 인스턴스를 반환하는 방법입니다. 초기화 로직을 포함 할 수 있습니다. 다음은 생성자의 예입니다. 다음 코드를 사용하여, 당신은 SomeClass에 액세스 할 수 있다고 가정 개체 이니셜 라이저를 사용하여 첫 번째 예에서와 같이


public class Foo 
{ 
    public SomeClass s { get; set; } 
    public Foo() {} 
} 

당신은 동일한 결과를 얻을 수 있습니다 :


public class Foo 
{ 
    private SomeClass s; 
    public Foo(string s) 
    { 
     s = new SomeClass(s); 
    } 
} 

이제 다음 예를 살펴


new Foo() { s = new SomeClass(someString) } 

볼 수 있듯이 개체 이니셜 라이저를 사용하면 제작이 수행 될 때 공용 필드와 공개 (설정 가능한) 속성의 값을 지정할 수 있으며 t 모자는 생성자가 특정 필드를 초기화하는 오버로드를 제공하지 않을 때 특히 유용합니다. 객체 초기화는 단지 구문 설탕 일 뿐이며 컴파일 후에는 할당 시퀀스와 실제 차이가 없다는 점에 유의하십시오.

11

제대로 작동하려면 개체에 대해 반드시 속성을 설정해야합니다. 한 가지 방법은 이러한 필수 속성을 매개 변수로 요구하는 단 하나의 생성자 만 노출하는 것입니다.

그런 경우 이러한 필수 속성을 지정하지 않고 개체를 만들 수 없습니다. 객체 초기화 프로그램에서는 이와 같은 것을 적용 할 수 없습니다.

개체 이니셜 라이저는 실제로 초기 할당을 줄이기위한 "구문 편리 성"에 불과합니다. 멋지지만 실제로는 기능적으로 적절하지 않습니다.

마크

+0

건설 시간에 필수 속성이 개체에 설정되도록하는 또 다른 방법은 생성 된 개체를 반환하는 클래스에 정적 ("팩토리") 메서드를 제공하는 것입니다. 이 팩토리 메소드는 * private * 생성자를 통해 객체를 생성합니다. – DavidRR

+0

... 하나 이상의 다른 클래스의 인스턴스를 생성하는 책임이있는 정적 팩토리 * 클래스 *를 만드는 것이 유용 할 때도 있습니다. 예를 들어 [File.Create Method (String)] (https://docs.microsoft.com/en-us/dotnet/api/system.io.file.create?view=netframework-4.7.1#System_IO_File_Create_System_String_) (및 그것의 오버로드)를 생성하는 'FileStream' 객체. – DavidRR

17

이 개체 이니셜 라이저는 본질적으로 무엇이다 :

Person tmp = new Person(); //creates temp object calling default constructor 
tmp.Name = "a"; 
tmp.Age = 23; 
p = tmp; 

지금이 this 같은 동작을 용이하게합니다. 객체 이니셜 라이저의 작동 방식을 아는 것은 중요합니다.

+0

Person p = new Person {Name = "a" }? –

+0

@ nick-s 예, 대단히. 이것은 객체 이니셜 라이저를위한 것입니다. 원하는 멤버를 초기화합니다. – nawfal

+2

생성자 paranthesis를 건너 뛸 수 있다는 것을 알지 못했습니다. 감사. –