C#의 개인 생성자로 개체를 인스턴스화하는 방법은 무엇입니까?
-
22-08-2019 - |
문제
나는 반사 나 무언가를 사용하여 그렇게하는 예를 보는 것을 기억합니다. 그것은 관련이있는 것이 었습니다 SqlParameterCollection
사용자는 생성 할 수 없습니다 (실수하지 않은 경우). 불행히도 더 이상 찾을 수 없습니다.
누구든지 여기서이 트릭을 공유 할 수 있습니까? 나는 그것이 개발에서 유효한 접근법이라고 생각하는 것이 아니라,이를 수행 할 가능성에 매우 관심이 있습니다.
해결책
// the types of the constructor parameters, in order
// use an empty Type[] array if the constructor takes no parameters
Type[] paramTypes = new Type[] { typeof(string), typeof(int) };
// the values of the constructor parameters, in order
// use an empty object[] array if the constructor takes no parameters
object[] paramValues = new object[] { "test", 42 };
TheTypeYouWantToInstantiate instance =
Construct<TheTypeYouWantToInstantiate>(paramTypes, paramValues);
// ...
public static T Construct<T>(Type[] paramTypes, object[] paramValues)
{
Type t = typeof(T);
ConstructorInfo ci = t.GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic,
null, paramTypes, null);
return (T)ci.Invoke(paramValues);
}
다른 팁
과부하 중 하나를 사용할 수 있습니다 Activator.CreateInstance 이것을하기 위해: Activator.CreateInstance(Type type, bool nonPublic)
사용 true
용 nonPublic
논쟁. 왜냐하면 true
공개 또는 비공개 기본 생성자와 일치합니다. 그리고 false
공개 기본 생성자 만 일치합니다.
예를 들어:
class Program
{
public static void Main(string[] args)
{
Type type=typeof(Foo);
Foo f=(Foo)Activator.CreateInstance(type,true);
}
}
class Foo
{
private Foo()
{
}
}
이것이 당신이 후에 있었던 질문입니까?Activator. 개인 밀봉 클래스를 사용하여 생성기를 만듭니다
수업이 당신의 것 중 하나가 아니라면,이를 방지하기 위해 API가 의도적으로 작성된 것처럼 들립니다. 즉, API 작가가 의도 한 것이 아닐 수 있습니다. 문서를 살펴 보고이 클래스 사용에 권장되는 접근 방식이 있는지 확인하십시오.
만약 너라면 하다 클래스를 제어 하고이 패턴을 구현하려면 일반적으로 클래스의 정적 메소드를 통해 구현됩니다. 이것은 싱글 톤 패턴을 구성하는 핵심 개념입니다.
예를 들어:
public PrivateCtorClass
{
private PrivateCtorClass()
{
}
public static PrivateCtorClass Create()
{
return new PrivateCtorClass();
}
}
public SomeOtherClass
{
public void SomeMethod()
{
var privateCtorClass = PrivateCtorClass.Create();
}
}
sqlcommandparameter 물건이 좋은 예입니다. 그들은 다음과 같은 것을 호출하여 매개 변수를 만들 것으로 기대합니다.
var command = IDbConnnection.CreateCommand(...);
command.Parameters.Add(command.CreateParameter(...));
내 예제는 명령 매개 변수 속성을 설정하거나 매개 변수/명령의 재사용을 보여주지 않기 때문에 훌륭한 코드가 아니지만 아이디어를 얻습니다.
당신의 경우에도 도움이 될 것입니다 Type
~이다 private
또는 internal
:
public static object CreatePrivateClassInstance(string typeName, object[] parameters)
{
Type type = AppDomain.CurrentDomain.GetAssemblies().
SelectMany(assembly => assembly.GetTypes()).FirstOrDefault(t => t.Name == typeName);
return type.GetConstructors()[0].Invoke(parameters);
}