문제

다음 수업을 예로 들어 보겠습니다.

class Sometype
{
    int someValue;

    public Sometype(int someValue)
    {
        this.someValue = someValue;
    }
}

그런 다음 반사를 사용 하여이 유형의 인스턴스를 만들고 싶습니다.

Type t = typeof(Sometype);
object o = Activator.CreateInstance(t);

그러나 일반적으로 이것은 효과가 있습니다 SomeType 매개 변수가없는 생성자, 호출을 정의하지 않았습니다. Activator.CreateInstance 유형의 예외를 던질 것입니다 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;
}

이것은 생성 표현식이 효과적으로 캐시되고 유형이 처음로드 된 경우에만 페널티를 제공한다는 것을 의미합니다. 효율적인 방식으로 가치 유형도 처리합니다.

불러라:

MyType me = New<MyType>.Instance();

주목하십시오 (T)FormatterServices.GetUninitializedObject(t) 문자열에 실패합니다. 따라서 빈 문자열을 반환하기 위해 문자열의 특수 처리가 마련되어 있습니다.

좋은 답변이지만 Dot Net Compact 프레임 워크에서는 사용할 수 없습니다. 다음은 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);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top