简体   繁体   English

如何在没有第二个声明类型的情况下将辅助泛型参数传递给泛型类构造函数

[英]How to pass a secondary generic parameter to a generic class constructor without a second declare type

It is the first time i have gotten this requirement and i can't figure out how to make it work.这是我第一次得到这个要求,我不知道如何使它工作。 I have a class that has a generic type.我有一个具有泛型类型的类。 Then the constructor need to get an object of that type.然后构造函数需要获取该类型的对象。 So far so good.到现在为止还挺好。 Now that same constructor need to receive a secondary generic type as a parameter of that constructor without having to define a second generic type in the class.现在,同一个构造函数需要接收第二个泛型类型作为该构造函数的参数,而不必在类中定义第二个泛型类型。 So here some sample code simplified for understanding purpose所以这里简化了一些示例代码以供理解

// a base class
public class Item {}

// one of many derived class
public class Switch : Item {}

// another class but unrelated to item
public class Sheet {}

// a derived of sheet
public class CoinSheet : Sheet {}

Now i need a generic class that has an Item as a type so a basic class would be the following and it works perfectly现在我需要一个具有 Item 作为类型的泛型类,因此基本类如下所示,它可以完美运行

public class Manager<T> where T : Item
{
    public T RelatedItem { get; set; } = null;
    
    public Manager(T relatedItem)
    {
        RelatedItem = relatedItem;
    }
}

The problem is that i now need to pass an object of type Sheet to the constructor without specifing it in the generic of the class.问题是我现在需要将Sheet类型的对象传递给构造函数,而无需在类的泛型中指定它。 The following does NOT work but it's that i mean by that (based on the previous class definition以下不起作用,但我的意思是(基于以前的类定义

public class Manager<T> where T : Item
{
    public T RelatedItem { get; set; } = null;
    
    public Manager(T relatedItem, T2 relatedSheet) where T2 : Sheet
    {
        RelatedItem = relatedItem;
        InstanceGenerator.Create<T2>(relatedSheet);
    }
}

I proposed to call a method within the Manager class instead that can have the secondary generic type without altering the Manager class definition (which cannot change) but i was given a definitive no as an answer.我建议在Manager类中调用一个方法,该方法可以在不改变Manager类定义(不能更改)的情况下具有辅助泛型类型,但我得到了一个明确的“否”作为答案。

I know i can just change the parameter type of that second parameter to object and forget about generic and just hardcode the check for if the object is of type Sheet and find by reflection the InstanceGenerator.Create and invoke it but if it's avoidable i rather do so.我知道我可以将第二个参数的参数类型更改为object并忘记泛型,只需硬编码检查object是否为Sheet类型并通过反射找到InstanceGenerator.Create并调用它,但如果它是可以避免的,我宁愿这样做所以。

If you don't add it to the class, you can't add it to the constructor.如果不将其添加到类中,则无法将其添加到构造函数中。

public class Manager<T> where T : Item
{
    public T RelatedItem { get; set; } = null;
    // THIS IS INVALID
    public Manager<T2>(T relatedItem, T2 relatedSheet) where T2 : Sheet
    {
        RelatedItem = relatedItem;
        InstanceGenerator.Create<T2>(relatedSheet);
    }
}

Which makes sense.这是有道理的。 The constructor will only be called once, so there is no point changing the T2 in the constructor if it is to affect the method.构造函数只会被调用一次,因此如果要影响方法,更改构造函数中的 T2 没有意义。

Your two real options are你的两个真正的选择是

  1. Direct use of Sheet.直接使用Sheet。
public class Manager<T> where T : Item
{
    public T RelatedItem { get; set; } = null;
    
    public Manager(T relatedItem, Sheet relatedSheet)
    {
        RelatedItem = relatedItem;
        InstanceGenerator.Create<T2>(relatedSheet);
    }
}
  1. The T2 to be added on class level.要在班级级别添加的 T2。

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

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