【问题标题】:Is there a way to pass an argument to a class constructor when used as a type parameter?当用作类型参数时,有没有办法将参数传递给类构造函数?
【发布时间】:2019-06-28 05:49:05
【问题描述】:

我正在尝试使我的代码尽可能地可重用,但在尝试将构造函数参数传递给用作类型参数的类时遇到了问题。

我目前拥有的是这样的:

    public sealed class SubmitForm : DerivedClass
    {            
    }

    public void TestMethod_Simulated()
    {
        var foo = GetObject<SubmitForm>();
        SubmitData(foo);
    }

    private void SubmitData(SubmitForm form)
    {
        // Do work 
    }

    public T GetObject<T>()
        where T : class
    {
        // Work
    }

这是有效的,因为 SubmitForm 没有显式的构造函数和参数。但是我想扩展功能并需要一个需要参数的显式构造函数。

添加构造函数后,我希望使用类型参数“SubmitForm”调用“GetObject”,包括其显式构造函数的参数。

这显然不可能以任何直接的方式实现,但我不想相信没有办法让它发挥作用。

下面显示了我想要实现的目标,即在实例化它时将类用作类型参数,以便访问我创建的构造函数:

    public sealed class SubmitForm : DerivedClass
    {
        public SubmitForm(EnumType typeVar)
        {
            _derivedVar = typeVar;
        }
    }

    public void TestMethod_Simulated()
    {
        var foo = GetObject<new SubmitForm(EnumType.FormA)>();
        SubmitData(foo);
    }

    private void SubmitData(SubmitForm form)
    {
        // Do work 
    }

    public T GetObject<T>()
        where T : class
    {
        // Work
    }

我希望这是有道理的。我似乎找不到一种方法来首先实例化该类,然后将其用作类型参数。

【问题讨论】:

  • SubmitData 方法期望的参数类型是什么?
  • 抱歉,我已经包含了 SubmitData 方法的签名 - 它的参数类型是“SubmitForm”
  • 你想让GetObject使用特定的构造函数创建一个SubmitForm对象吗?
  • 不,我关心的不是 GetObject。GetObject 是现有的通用代码,用于构造要与 SubmitData 一起使用的过滤器对象。我的问题是我想用正确的表单类型参数(根据构造函数)实例化我的 SubmitForm 类,以便 GetObject 可以基于该构造函数创建正确的过滤器对象。这样做的原因是因为各种表单将使用相同的类,但不同的表单类型除外。

标签: c# types parameters constructor arguments


【解决方案1】:

我希望这是有道理的。我似乎找不到第一个方法 实例化该类,然后将其用作类型参数

好吧,不可能将类的实例作为泛型类型参数传递。 类型参数只是对象类型的 占位符。编译器使用它来推断类型并将T 替换为真实类型。与实际参数无关。

如果您想在函数中使用SubmitForm 类的特定实例,您可以先创建一个实例:

var submitForm = new SubmitForm(EnumType.FormA);

然后更改您的函数以接受T 类型的参数:

public T GetObject<T>(T instance)
    where T : class
{
   // .. do something with instance
}

现在您可以调用新的重载:

var someResult = GetObject(submitForm);

但是,从您的代码示例中,您根本不清楚为什么需要泛型类型参数。看来你不妨把GetObject函数的签名从T GetObject&lt;T&gt;()改成SubmitForm GetObject(SubmitForm form)

当我们有一个泛型函数需要为不同类型执行或多或少相同的逻辑并且我们不想重复相同的代码时,我们通常使用类型参数。

【讨论】:

  • 谢谢法布詹。我从没想过将 GetObject 代码修改为遗留系统的一部分,我也不想弄乱它。但是,为了实现我想要的,我遵循了您的建议,并将“实例”添加为 T 类型的可选参数,所以现在我正在实例化该类并将其交给 GetObject 方法。我相信这会奏效。这个系统的现有代码极其复杂,继承层次严重,泛型很多,所以我仍然不完全理解开发者实现的复杂性和架构背后的原因。
  • @jpsqr 不客气。免费建议 - 尽可能多地为您的问题添加有用信息。例如,您无法控制GetObject 代码并且它来自遗留库的这条信息很重要。将其添加到您的问题中,您将获得更好、更准确的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2015-10-11
  • 1970-01-01
相关资源
最近更新 更多