program tip

유형이 매개 변수없는 생성자를 제공하는지 어떻게 확인합니까?

radiobox 2020. 8. 25. 07:53
반응형

유형이 매개 변수없는 생성자를 제공하는지 어떻게 확인합니까?


런타임에 알려진 유형이 매개 변수없는 생성자를 제공하는지 확인하고 싶습니다. Type내가 반사를 사용할 필요가 있으리라 믿고있어, 그래서 클래스는 약속 아무것도 양보하지 않았다?


Type클래스 입니다 반사. 넌 할 수있어:

Type theType = myobject.GetType(); // if you have an instance
// or
Type theType = typeof(MyObject); // if you know the type

var constructor = theType.GetConstructor(Type.EmptyTypes);

매개 변수없는 생성자가 없으면 null을 반환합니다.


개인 생성자를 찾으려면 약간 더 긴 것을 사용하십시오.

var constructor = theType.GetConstructor(
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
  null, Type.EmptyTypes, null);

기본 생성자를 가질 수없는 값 유형에 대한주의 사항이 있습니다 . Type.IsValueType속성을 사용하여 값 유형이 있는지 확인 하고 Activator.CreateInstance(Type); 를 사용하여 인스턴스를 만들 수 있습니다 .


type.GetConstructor(Type.EmptyTypes) != null

structs에 대해 실패합니다 . 확장하는 것이 좋습니다.

public static bool HasDefaultConstructor(this Type t)
{
    return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}

조차도 enum기본 매개 변수가없는 생성자를 가지 므로 성공합니다 . 또한 리플렉션 호출이 수행되지 않기 때문에 값 유형에 대해 약간의 속도가 빨라집니다.


네, Reflection을 사용해야합니다. 하지만 이미 사용할 때GetType()

다음과 같은 것 :

var t = x.GetType();
var c = t.GetConstructor(new Type[0]);
if (c != null) ...

이것은 작동합니다.

   myClass.GetType().GetConstructors()
                    .All(c=>c.GetParameters().Length == 0)

상황에 따라 일반 유형 제한을 사용할 수도 있습니다.

public void DoSomethingWith<T>(T myObject) where T:new() {...}

위의 메서드 선언은 매개 변수없는 생성자로 인스턴스화 할 수있는 모든 개체로 매개 변수 유형을 제한합니다. 여기서 장점은 컴파일러가 매개 변수없는 생성자가없는 클래스에서 메서드를 사용하려는 모든 시도를 포착한다는 것입니다. 이전에 문제.

물론 유형이 실제로 런타임에만 알려진 경우 (즉, Activator.CreateInstance ()를 사용하여 문자열 또는 구성된 유형을 기반으로 객체를 인스턴스화하는 경우) 이것은 도움이되지 않습니다. 저는 일반적으로 반사를 절대적인 마지막 옵션으로 사용합니다. 왜냐하면 일단 다이나믹 랜드에 가면 다이나믹 랜드에 머물러야하기 때문입니다. 일반적으로 무언가를 동적으로 인스턴스화 한 다음 정적으로 처리하기 시작하는 것은 어렵거나 더 복잡합니다.


예, 반사를 사용해야합니다.

object myObject = new MyType();
Type type = myObject.GetType();
ConstructorInfo conInfo = type.GetConstructor(new Type[0]);

매개 변수가없는 실제 생성자와 동일한 선택적 매개 변수 만있는 생성자를 계산해야했습니다 . 이것을하기 위해:

myClass.GetType().GetConstructors()
    .All(c => c.GetParameters().Length == 0 || c.GetParameters().All(p => p.IsOptional))

"공식"버전에 관심이있는 사람은 .NET Reflector 를 통해 다음을 찾았습니다 .

from: System.Activities.Presentation.TypeUtilities
in System.Activities.Presentation.dll, Version=4.0.0.0

public static bool CanCreateInstanceUsingDefaultConstructor(this Type t) => 
                t.IsValueType || !t.IsAbstract && t.GetConstructor(Type.EmptyTypes) != null;

Notice the check for t.IsAbstract, which is not mentioned elsewhere on this page.

You can also expand the GetConstructor call out as follows, if you feel like micro-optimizing away one stack frame:

…t.GetConstructor(BindingFlags.Public|BindingFlags.Instance, null, Type.EmptyTypes, null)…

참고URL : https://stackoverflow.com/questions/4681031/how-do-i-check-if-a-type-provides-a-parameterless-constructor

반응형