WCF反序列化有一些神奇之处.如何在不调用其构造函数的情况下实例化数据协定类型的实例?
例如,考虑这个数据合同:
[DataContract]
public sealed class CreateMe
{
   [DataMember] private readonly string _name;
   [DataMember] private readonly int _age;
   private readonly bool _wasConstructorCalled;
   public CreateMe()
   {
      _wasConstructorCalled = true;
   }
   // ... other members here
}
通过DataContractSerializer您获取此对象的实例时,您将看到该字段_wasConstructorCalled是false.
那么,WCF如何做到这一点?这是其他人可以使用的技术,还是隐藏在我们之外?
我正在努力提高应用程序的性能.我们有很多Activator.CreateInstance调用引起了一些悲伤.
我们基于一个接口(ITabDocument)实例化了很多类,在浏览后我想到了使用这段代码:
代码并不比使用我们拥有的Activator.CreateInstance代码更好(实际上稍慢).
    public static Func<T> CreateInstance<T>(Type objType) where T : class, new()
    {
        var dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + objType.Name, objType, null, objType);
        ILGenerator ilGen = dynMethod.GetILGenerator();
        ilGen.Emit(OpCodes.Newobj, objType.GetConstructor(Type.EmptyTypes));
        ilGen.Emit(OpCodes.Ret);
        return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));
    }
我想知道为什么会这样,我所做的只是:
ITabDocument document = CreateInstance<ITabDocument>(Type.GetType("[Company].Something"));
是否有更好的方法来创建有助于上述内容的对象?当你不确定具体的类型时,它有点难.
在工作中阅读现有代码,我想知道这怎么可行.我有一个在程序集中定义的类:
[Serializable]
public class A
{
    private readonly string _name;
    private A(string name)
    {
        _name = name;
    }
}
在另一个集会中:
public void f(Type t) {
    object o = Activator.CreateInstance(t);
}
那个简单的电话 f(typeof(A))
我期望缺少无参数构造函数的例外,因为AFAIK,如果声明了ctor,编译器不应该生成默认的公共无参数构造函数.
此代码在.NET 2.0下运行.
[编辑]我很抱歉,但我误读了实际的代码...我提供的示例没有说明它.我接受了JonH的答案,因为它提供了一个很好的信息.
如果想要创建泛型的新实例,则需要定义新约束,如下所示:
public T SomeMethod<T>() where T : new()
{
    return new T();
}
是否可以使用反射在没有新约束的情况下创建T的实例,如此(包含伪代码):
public T SomeMethod<T>()
{
    if (T has a default constructor)
    {
        return a new instance of T;
    }
    else
    {
        return Factory<T>.CreateNew();
    }
}
我和朋友正在测试使用编译表达式来创建对象,而不是Activator.CreateInstance<T>遇到一些有趣的结果.我们发现当我们在每台机器上运行相同的代码时,我们看到完全相反的结果.他得到了预期的结果,在编译表达式中表现明显更好,而我惊讶地看到Activator.CreateInstance<T>表现为2x.
两台计算机都运行在.NET 4.0中编译
计算机1安装了.NET 4.5.电脑2没有.
计算机1超过100000个对象:
45ms - Type<Test>.New()
19ms - System.Activator.CreateInstance<Test>();
计算机2超过100000个对象:
13ms - Type<Test>.New()
86ms - System.Activator.CreateInstance<Test>();
以下是代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
namespace NewNew
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch benchmark = Stopwatch.StartNew();
            for (int i = 0; i < 100000; i++)
            {
                var result = Type<Test>.New();
            }
            benchmark.Stop();
            Console.WriteLine(benchmark.ElapsedMilliseconds + " Type<Test>.New()");
            benchmark = Stopwatch.StartNew();
            for (int i = 0; i < 100000; …我开始阅读关于反射的内容,我想知道有没有办法在程序运行时创建构造函数。例如:获取类 C 并检查 C 是否有空构造函数,如果没有,则创建并使用它来创建此实例。构造函数也可能有参数。
我怎样才能做到这一点?谢谢
我正在为别人的代码编写单元测试,我不允许修改.
说我有:
class BadClass
{
    public BadClass()
    {
        // the service isn't going to be running during testing
        // it also has no interface
        someFlag = AGloballyStoredService.getSomeFlag();
    }
    public bool someFlag;
}
用于:
class AnotherBadClass
{
    public AnotherBadClass(BadClass badClass)
    {
        someFlag = badClass.someFlag;
    }
    public bool someFlag;
}
说我想要测试:
public void AnotherBadClassConstructorTest()
{
    BadClass badClass = new BadClass();
    AnotherBadClass anotherBadClass = new AnotherBadClass(badClass);
    Assert.IsNotNull(anotherBadClass);
}
我想模拟BadClass,但它没有接口,如果服务没有运行,它在构造函数中失败.
考虑到我无法修改我正在测试的代码,是否有一种直接的方法来使其工作?
如果归结为它,我可以告诉他们,他们必须让我修改现有的代码库或接受该模块的10%以下的覆盖率.
我想知道为什么一个class不能serialization没有空构造函数。
当我收到此错误消息时,我尝试了几次:
ClassName cannot be serialized because it does not have a parameterless constructor.
代码是这样的:
   public void DoSerialize(string path)
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
            TextWriter textWriter = new StreamWriter(path);
            serializer.Serialize(textWriter, MyList);
            textWriter.Close();
        }
        catch (Exception e)
        {
        }
    }
真的,当我添加一个空的构造函数时,它起作用了