实例化没有公共构造函数的.NET类

时间:2015-07-30 00:52:31

标签: c# .net

如何在没有公共构造函数的情况下实例化一个类(并且没有静态工厂方法)。具体来说,我尝试将.NET ElapsedEventArgs类与我的自定义计时器类一起使用,但是创建它的新对象是不可能的。如果你不能实例化System.Timers.Timer怎么做呢?创建类似的类EventArgs的首选方法是什么?

2 个答案:

答案 0 :(得分:5)

  

如果你无法实例化ElapsedEventArgs怎么做呢?

internal ElapsedEventArgs(int low, int high) { long fileTime = (long)((((ulong)high) << 32) | (((ulong)low) & 0xffffffff)); this.signalTime = DateTime.FromFileTime(fileTime); } 有一个构造函数,但它是内部的,所以只有在同一个程序集中声明的代码才能调用它。您可以在sourceof.net上看到它:

EventArgs
  

创建类似类的首选方式是{{1}}吗?

是的,我会这么说。

答案 1 :(得分:2)

可以使用Reflection访问非公共构造函数。您应该记住,Microsoft将该类定义为内部,因此可以自由地重新定义构造函数的签名而不必担心破坏您的代码,但我认为使用ElapsedEventArgs几乎不可能发生这种情况。

以下示例演示了执行此操作的代码:

using System;
using System.Reflection;
using System.Timers;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var constructorInfo = typeof(ElapsedEventArgs).GetConstructor(
                BindingFlags.NonPublic | BindingFlags.Instance, 
                null, new [] { typeof(int), typeof(int) }, null);
            var elapsedEventArgs = (ElapsedEventArgs)
                constructorInfo.Invoke(new object[] { 50, 50 });
        }
    }
}

此类的构造函数签名是复杂的,要求您提供DOS FILETIME结构的高和低组件;它不是非常用户友好,并且Reflection的性能非常差,所以如果你有一个场景,你经常提出这些事件,如果可能是一个问题。反思因缓慢而闻名(而且来之不易);它应该谨慎使用,并且只有当它是你唯一的选择时才使用。

我会使用一个简单的构造函数创建我自己的EventArgs类,该构造函数具有DateTime格式的当前时间,如以下示例所示:

using System;
using System.Timers;

public class MyElapsedEventArgs : EventArgs
{
    public MyElapsedEventArgs(DateTime fireTime)
    {
        FireTime = fireTime;
    }

    public DateTime FireTime { get; private set; }
}

然后你会这样举起事件:

raise_event(new MyElapsedEventArgs(new DateTime.Now));

Easy breazy。