简体   繁体   English

允许可选的构造函数参数传递给`T` 方法吗?

[英]Allowing optional constructor parameters to `T` method?

I have this method that creates an instance of a class, measures the time it takes to load the class, and has the option to call a method.我有这个方法来创建一个类的实例,测量加载类所花费的时间,并且可以选择调用一个方法。 I'm currently trying to implement the option to pass parameters to the constructor of this method (IE T ) but I'm a bit stuck, can anyone help?我目前正在尝试实现将参数传递给此方法(IE T )的构造函数的选项,但我有点卡住了,有人可以帮忙吗?

public static T CreateInstanceOf<T>(Action<T> configure = null) where T : new()
{
    var stopwatch = Stopwatch.StartNew();

    var result = new T();

    configure?.Invoke(result);

    stopwatch.Stop();

    Logger.Trace("Loaded " + result.GetType().Name + " [took " + stopwatch.ElapsedMilliseconds + "ms]");

    return result;
}

It's much easier if you keep the work of creating class instances out of this method, since the purpose isn't really to create objects - you just want to time the constructors.如果您将创建类实例的工作保留在此方法之外,则要容易得多,因为目的并不是真正创建对象 - 您只想为构造函数计时。 You could write your method like this instead:你可以这样写你的方法:

public T TimeCreationOf<T>(Func<T> creator, Action<T> configure = null)
{
    var stopwatch = Stopwatch.StartNew();

    var result = creator.Invoke();

    configure?.Invoke(result);

    stopwatch.Stop();

    Logger.Trace("Loaded " + result.GetType().Name + " [took " + stopwatch.ElapsedMilliseconds + "ms]");

    return result;
}

(Since you're just timing, do you need this method to return the instance of T that was created?) (既然你只是计时,你是否需要这个方法来返回创建的T的实例?)

Now what you pass into this method is a function that returns a T .现在你传递给这个方法的是一个返回T的函数。 And since what you want to time is the constructor, you can just pass in a function that calls the constructor and returns an instance of T .由于您想要计时的是构造函数,因此您可以传入一个调用构造函数并返回T实例的函数。

This makes it much easier because you don't need the new() constraint - T could be any type with any sort of constructor.这使它变得更容易,因为您不需要new()约束 - T可以是具有任何类型构造函数的任何类型。 And you don't need to worry about how the "timing" method will call the constructors - the functions you're passing in do that for you:而且您无需担心“计时”方法将如何调用构造函数 - 您传入的函数会为您完成此操作:

TimeCreationOf(() => new ClassOne());
TimeCreationOf(() => new ClassTwo(5, "X"));

Because you're calling the constructors directly you know exactly which constructor you want to call and what to pass to it.因为您直接调用构造函数,所以您确切地知道要调用哪个构造函数以及传递给它的内容。 If you tried to write a generic method that could create all sorts of objects it would be really difficult.如果您试图编写一个可以创建各种对象的通用方法,那将非常困难。

And if you still need to pass in another Action<T> that performs some additional configuration on the object (and you want to include that in the timing) you can do that as well.如果您仍然需要传入另一个Action<T>来对对象执行一些额外的配置(并且您希望将其包含在时间中),您也可以这样做。

TimeCreationOf(() => new ClassTwo(), c =>
{
    c.SomeProperty = "x";
    c.DoSomethingElse();
});

T is not a method - it's a generic type, that you have required have a parameterless constructor, which you are calling. T不是一个方法——它是一个泛型类型,你需要一个无参数的构造函数,你正在调用它。 Since there's not a syntax to specify that the type implement a specific constructor signature, you're left with two options:由于没有语法来指定类型实现特定的构造函数签名,因此您有两个选择:

  1. Use reflection (eg Activator.CreateInstance ) to pass parameters to the constructor and hope that whatever T is at runtime supports those parameters, or使用反射(例如Activator.CreateInstance )将参数传递给构造函数,并希望运行时T支持这些参数,或者
  2. Require that T implement some interface that you can use to initialize the object:要求T实现一些可用于初始化对象的接口:

     public interface IInitializable { public void Init(...parameters...) } public static T CreateInstanceOf<T>(Action<T> configure = null) where T : new(), IInitializable { T = new T(); T.Initialize(...parameters...); ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM