둘 사이의 차이점은 무엇이며 "개체 이니셜 라이저"를 "생성자"에 사용하는 경우와 그 반대의 경우는 무엇입니까? 그게 중요하다면 나는 C#으로 일하고있다. 또한 C# 또는 .NET에 특정한 객체 이니셜 라이저 메서드가 있습니까?개체 이니셜 라이저와 생성자의 차이점은 무엇입니까?
답변
개체 이니셜 라이저는 객체를 사용할 때 뭔가의 건설을 단순화하기 위해, C# 3에 추가했다.
생성자는 0 개 이상의 매개 변수를 제공, 실행 및 호출 방법은 생성 된 객체에 대한 핸들을 얻을 수 전에 객체 를 생성하고 초기화하는 데 사용됩니다.예를 들어이 경우
MyObject myObjectInstance = new MyObject(param1, param2);
, MyObject
의 생성자는 값 param1
및 param2
으로 실행됩니다. 이것들은 모두 메모리에 새로운 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 };
을 수행 할 때
생성자는 지정된 수의 매개 변수를 사용하여 개체를 만들고 초기화하는 형식에 대해 정의 된 메서드입니다.
개체 이니셜 라이저는 생성자 다음에 개체에서 실행되는 코드로, 개체의 모든 필드를 지정된 값으로 간결하게 설정하는 데 사용할 수있는 코드입니다. 이 필드의 설정은 후에 생성자가 호출 된 후 이 발생합니다.
생성자가 개체의 초기 상태를 충분히 설정 한 경우 개체 이니셜 라이저를 사용하지 않고 생성자를 사용합니다. 그러나 객체 이니셜 라이저는 생성자와 함께 사용해야합니다. 구문을 사용하면 초기 개체를 만들기 위해 생성자의 명시 적 또는 암시 적 사용 (VB.Net 및 C#)이 필요합니다. 생성자가 객체를 사용하기에 충분하게 초기화하지 않고 몇 가지 간단한 필드 및/또는 속성 집합을 만들 때 객체 이니셜 라이저를 사용합니다.
"after"노트가 중요합니다. – user8032
생성자는 매개 변수를 받아들이고 클래스의 새 인스턴스를 반환하는 방법입니다. 초기화 로직을 포함 할 수 있습니다. 다음은 생성자의 예입니다. 다음 코드를 사용하여, 당신은 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 모자는 생성자가 특정 필드를 초기화하는 오버로드를 제공하지 않을 때 특히 유용합니다. 객체 초기화는 단지 구문 설탕 일 뿐이며 컴파일 후에는 할당 시퀀스와 실제 차이가 없다는 점에 유의하십시오.
제대로 작동하려면 개체에 대해 반드시 속성을 설정해야합니다. 한 가지 방법은 이러한 필수 속성을 매개 변수로 요구하는 단 하나의 생성자 만 노출하는 것입니다.
그런 경우 이러한 필수 속성을 지정하지 않고 개체를 만들 수 없습니다. 객체 초기화 프로그램에서는 이와 같은 것을 적용 할 수 없습니다.
개체 이니셜 라이저는 실제로 초기 할당을 줄이기위한 "구문 편리 성"에 불과합니다. 멋지지만 실제로는 기능적으로 적절하지 않습니다.
마크
건설 시간에 필수 속성이 개체에 설정되도록하는 또 다른 방법은 생성 된 개체를 반환하는 클래스에 정적 ("팩토리") 메서드를 제공하는 것입니다. 이 팩토리 메소드는 * private * 생성자를 통해 객체를 생성합니다. – DavidRR
... 하나 이상의 다른 클래스의 인스턴스를 생성하는 책임이있는 정적 팩토리 * 클래스 *를 만드는 것이 유용 할 때도 있습니다. 예를 들어 [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
이 개체 이니셜 라이저는 본질적으로 무엇이다 :
Person tmp = new Person(); //creates temp object calling default constructor
tmp.Name = "a";
tmp.Age = 23;
p = tmp;
지금이
this 같은 동작을 용이하게합니다. 객체 이니셜 라이저의 작동 방식을 아는 것은 중요합니다.
Person p = new Person {Name = "a" }? –
@ nick-s 예, 대단히. 이것은 객체 이니셜 라이저를위한 것입니다. 원하는 멤버를 초기화합니다. – nawfal
생성자 paranthesis를 건너 뛸 수 있다는 것을 알지 못했습니다. 감사. –
나는 동의하지만, 특히 디버깅 객체 이니셜 라이저가 고통 스러울 수 있다고 덧붙이고 싶습니다. 특히 중첩 된 구조체 인 경우, 객체 이니셜 라이저가 문장 한 줄 (멋지게 형식화 된)으로 간주되기 때문에 중첩 된 구조가 있습니다. – CrnaStena
@ Reed-Copsey 아주 좋은 설명, 개체 이니셜 라이저를 사용하면 성능이 향상 될지 아니면 가독성을 위해서만 사용할까요? – Mahender
@Mahender 사실, 객체 이니셜 라이저를 사용할 때 일반적으로 (매우 작은) 성능 손실이 있습니다. 생성자는보다 효율적으로 작성 될 수 있습니다. –