当前位置:  开发笔记 > 编程语言 > 正文

使用反射在C#中创建没有默认构造函数的类型实例

如何解决《使用反射在C#中创建没有默认构造函数的类型实例》经验,为你挑选了3个好方法。

以下面的课程为例:

class Sometype
{
    int someValue;

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

然后我想使用反射创建这种类型的实例:

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

通常这会起作用,但是由于SomeType没有定义无参数构造函数,调用Activator.CreateInstance将抛出类型异常,MissingMethodException并带有消息" 没有为此对象定义无参数构造函数. "是否还有另一种方法可以创建此类型的实例?将无参数构造函数添加到我的所有类中会有点麻烦.



1> Jason Jackso..:

我最初在这里发布了这个答案,但这里有一个转载,因为这不是完全相同的问题,但有相同的答案:

FormatterServices.GetUninitializedObject()将在不调用构造函数的情况下创建实例.我通过使用Reflector并挖掘了一些核心的.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;
        }
    }
}


@JSBangs FormatterServices(http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.aspx)未记录.
@JSBangs,这很糟糕你是一个完全合法的答案.您的评论和其他答案实际上并未解决提出的问题.如果你觉得你有更好的答案,那就提供一个.但我提供的答案强调了如何使用文档类,就像其他序列化类使用此代码一样.
使用GetUninitializedObject似乎取决于您的具体目的:[因为对象的新实例初始化为零并且没有运行构造函数,因此该对象可能不表示该对象认为有效的状态.当用户打算立即填充所有字段时,当前方法只应用于反序列化.它不会创建一个未初始化的字符串,因为创建一个不可变类型的空实例是没有用的.](http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject.aspx )

2> Nick..:

使用CreateInstance方法的这个重载:

public static Object CreateInstance(
    Type type,
    params Object[] args
)

使用与指定参数最匹配的构造函数创建指定类型的实例.

请参阅:http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx



3> nawfal..:

当我对其性能进行基准测试时(T)FormatterServices.GetUninitializedObject(typeof(T)),速度较慢.同时,编译后的表达式可以提高速度,尽管它们仅适用于具有默认构造函数的类型.我采用了混合方法:

public static class New
{
    public static readonly Func Instance = Creator();

    static Func Creator()
    {
        Type t = typeof(T);
        if (t == typeof(string))
            return Expression.Lambda>(Expression.Constant(string.Empty)).Compile();

        if (t.HasDefaultConstructor())
            return Expression.Lambda>(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.Instance();

请注意,(T)FormatterServices.GetUninitializedObject(t)字符串将失败.因此,字符串的特殊处理就是返回空字符串.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有