내가 대답하려고하기 전에, 나는 당신이하는 일이 불필요한 것으로 지적해야한다고 생각합니다. 이 코드를 생성자에 넣으면 다음과 같이 생성됩니다.
public class Foo
{
private int a;
private bool b;
private SomeType c;
public Foo()
{
this.a = default(int);
this.b = default(bool);
this.c = default(SomeType);
}
}
은 필요하지 않습니다. 클래스가 생성되면 이 이미 자동으로 발생합니다. 실제로 JITter가 처리 할 수 있다고 가정 할지라도 실제로는 몇 가지 간단한 테스트를 통해 이러한 할당이 최적화되지 않은 것으로 나타납니다.
두 번째로 default
키워드가 설계되었습니다. 컴파일 할 때 유형을 알 수없는 변수에 "기본"값을 할당하는 방법을 제공하는 것이 중요합니다. 그것은 일반적인 코드에 의해 사용하기 위해 도입 된 것으로 추측되지만, 자동 생성 된 코드는이 코드를 사용할 때 확실히 맞습니다. 참조 형의 default
값이 너무, 새로운 List<int>
을 구성하지 않습니다
this.list = default(List<int>);
null
것을
이 명심, 그냥
null
에
this.list
을 설정합니다.당신이하고 싶다고 생각하는 대신
Type.IsValueType
속성을 사용하여 기본값에 값 유형을두고
new
을 사용하여 참조 유형을 초기화합니다.
마지막으로, 나는 당신이 여기에서 찾고있는 것은 Type
클래스의 IsGenericType
속성과 해당 GetGenericArguments()
방법이라고 생각 :
foreach (PropertyInfo property in properties)
{
if (property.Type.IsGenericType)
{
var subtypes = property.Type.GetGenericArguments();
// construct full type name from type and subtypes.
}
else
{
code += "this." + property.Name + " = default(" + property.PropertyType.Name + ")";
}
}
편집 : 지금까지 A에 대한 유용한 뭔가를 구성하는 등
참조 형식, 생성 된 코드에서 사용하는 일반적인 기술은 사용할 클래스의 매개 변수없는 생성자를 요구하는 것입니다. Type.GetConstructor()
을 호출하고 빈 Type[]
(예 : Type.EmptyTypes
)을 전달하고 매개 변수없는 생성자가 있는지 클래스를 확인하고 ConstructorInfo
또는 null
을 반환하는지 확인하는 것은 쉽습니다. 일단 설정이 완료되면 default(typename)
을 new typename()
으로 바꾸면 필요한 것을 얻을 수 있습니다.
더 일반적으로 일치하는 생성자가 있는지 확인하기 위해 해당 메서드에 대한 모든 배열 배열을 제공하거나 모두 GetConstructors()
을 호출하여 모두 가져올 수 있습니다. 여기서주의해야 할 점은 IsPublic
, IsStatic
및 IsGenericMethod
필드가 ConstructorInfo
인데이 코드가 생성되는 곳 어디에서나 실제로 호출 할 수있는 코드를 찾으십시오.
해결하려는 문제는 일부 제약 조건을 적용 할 수없는 이상 임의로 복잡해집니다. 하나의 옵션은 임의의 생성자를 찾아 다음과 같다 전화를 구축하는 것입니다 :
var line = "this." + fieldName + " = new(";
foreach (var param in constructor.GetParameters())
{
line += "default(" + param.ParameterType.Name + "),";
}
line = line.TrimEnd(',') + ");"
(아마 여기 된 CodeDom 사용하는 것, 이것은 단지 설명을위한 참고, 또는 적어도 모두 StringBuilder :
물론 지금은 generics가 될 수있는 각 매개 변수에 대해 적절한 유형 이름을 결정해야하는 문제가 있습니다. 그리고 참조 유형 매개 변수는 모두 null로 초기화됩니다. 그리고 당신이 선택할 수있는 임의의 많은 생성자 중 실제로 사용할 수있는 객체를 생성하는 방법을 알 수있는 방법이 없습니다. 인스턴스를 생성 한 직후에 속성을 설정하거나 메서드를 호출한다고 가정하는 것과 같이 나쁜 것들이있을 수 있습니다.
이러한 문제를 해결하는 방법은 기술적 인 것이 아닙니다. 사용자가 원하는만큼 멀리까지 각 매개 변수에 동일한 논리를 반복적으로 적용 할 수 있습니다. 사용 사례에 따라 사용자가 얼마나 복잡해야하며 어떤 종류의 제한을 사용자에게 제공할지 결정해야합니다.
'default (T)'를 사용하는 것이 왜 불편한 것인지 자세히 설명해 주시겠습니까? – svick
그것은 진부함이 아니지만 일반 사용자가 친숙 할 수있는 이니셜 라이저를 생성하기 위해 CodeDom을 사용하고 싶습니다. 여전히 기본 (T) 구성에 비틀 거릴 제네릭의 깊이를 보지 못한 많은 개발자가 있습니다. –
그리고 왜이 코드를 생성하고 있습니까? 모든 필드는 생성자가 실행되기 전에 기본값으로 설정됩니다. 여기에는 자동 속성의 백업 필드가 포함됩니다. – svick