다음 클래스를 예로 들어 보겠습니다.
class Sometype
{
int someValue;
public Sometype(int someValue)
{
this.someValue = someValue;
}
}
그런 다음 리플렉션을 사용하여이 유형의 인스턴스를 만들고 싶습니다.
Type t = typeof(Sometype);
object o = Activator.CreateInstance(t);
그러나 이것은 정상적으로 작동합니다.SomeType
매개 변수없는 생성자를 정의하지 않았습니다.Activator.CreateInstance
형식의 예외를 throw합니다.MissingMethodException
메시지 "이 객체에 대해 정의 된 매개 변수없는 생성자가 없습니다."이 유형의 인스턴스를 생성하는 또 다른 방법이 있을까요? 내 모든 클래스에 매개 변수없는 생성자를 추가하는 것은 다소 불편할 것입니다.
원래이 답변을 올렸습니다.이리, 그러나 이것은 똑같은 질문이 아니기 때문에 재발행입니다. 그러나 같은 대답을 가지고 있습니다 :
FormatterServices.GetUninitializedObject()
생성자를 호출하지 않고 인스턴스를 만듭니다. 나는이 수업을반사기일부 핵심 .NET 직렬화 클래스를 파고들 수 있습니다.
아래의 샘플 코드를 사용하여 테스트 한 결과 훌륭한 것으로 보입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
namespace NoConstructorThingy
{
class Program
{
static void Main(string[] args)
{
MyClass myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass)); //does not call ctor
myClass.One = 1;
Console.WriteLine(myClass.One); //write "1"
Console.ReadKey();
}
}
public class MyClass
{
public MyClass()
{
Console.WriteLine("MyClass ctor called.");
}
public int One
{
get;
set;
}
}
}
CreateInstance 메서드의 다음 오버로드를 사용합니다.
public static Object CreateInstance(
Type type,
params Object[] args
)
지정된 인스턴스를 작성합니다. 가장 잘 생성자를 사용하여 유형을 지정하십시오. 지정된 매개 변수와 일치합니다.
만나다:http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx
내가벤치마킹 된의 성능(T)FormatterServices.GetUninitializedObject(typeof(T))
그것은 더 느렸다. 동시에 컴파일 된 표현식은 기본 생성자가있는 유형에서만 작동하지만 속도가 크게 향상됩니다. 나는 하이브리드 접근 방식을 취했다 :
public static class New<T>
{
public static readonly Func<T> Instance = Creator();
static Func<T> Creator()
{
Type t = typeof(T);
if (t == typeof(string))
return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile();
if (t.HasDefaultConstructor())
return Expression.Lambda<Func<T>>(Expression.New(t)).Compile();
return () => (T)FormatterServices.GetUninitializedObject(t);
}
}
public static bool HasDefaultConstructor(this Type t)
{
return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
이는 create 표현식이 효과적으로 캐시되고 유형이 처음로드 될 때만 패널티가 발생 함을 의미합니다. 효율적인 방식으로 값 유형을 처리합니다.
불러라:
MyType me = New<MyType>.Instance();
유의 사항(T)FormatterServices.GetUninitializedObject(t)
문자열에 대해 실패합니다. 따라서 빈 문자열을 반환하기 위해 string에 대한 특수 처리가 제 위치에 있습니다.
좋은 답변이지만 닷넷 컴팩트 프레임 워크에서는 사용할 수 없습니다. CF.Net에서 작동하는 솔루션은 다음과 같습니다.
class Test
{
int _myInt;
public Test(int myInt)
{
_myInt = myInt;
}
public override string ToString()
{
return "My int = " + _myInt.ToString();
}
}
class Program
{
static void Main(string[] args)
{
var ctor = typeof(Test).GetConstructor(new Type[] { typeof(int) });
var obj = ctor.Invoke(new object[] { 10 });
Console.WriteLine(obj);
}
}
FormatterServices.GetUninitializedObject
초기화되지 않은 문자열을 만들 수 없습니다. 예외가 발생할 수 있습니다.System.ArgumentException: Uninitialized Strings cannot be created.
이를 명심하십시오. - Bartosz Pierzchlewicz