Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将参数传递给泛型类类型的构造函数_C#_Generics - Fatal编程技术网

C# 将参数传递给泛型类类型的构造函数

C# 将参数传递给泛型类类型的构造函数,c#,generics,C#,Generics,我已经编写了如下代码 public interface IScreenBuilder { void Build<TBusinessLogic, TPresenter, TForm> (ILog logger) where TPresenter : class, new() where TForm : class, new(); } public class ScreenBuilder: IScreen

我已经编写了如下代码

public interface IScreenBuilder
{
        void Build<TBusinessLogic, TPresenter, TForm> (ILog logger) 
            where TPresenter : class, new()
            where TForm : class, new();        
}

public class ScreenBuilder: IScreenBuilder
{
    private ILog _logger;
    public void Build<TBusinessLogic, TPresenter, TForm>(ILog logger)
           where TPresenter : class, new()
            where TForm : class, new()
    {
        _logger = logger;
        TBusinessLogic businessLogic = new BusinessLogicBuilder().Build<TBusinessLogic>();
        TPresenter presenter = new TPresenter(businessLogic);
                TForm form = new TForm(presenter);
    }
}
公共界面是ScreenBuilder
{
无效生成(ILog记录器)
其中TPresenter:class,new()
其中TForm:class,new();
}
公共类屏幕生成器:IScreenBuilder
{
私人ILog_记录器;
公共无效生成(ILog记录器)
其中TPresenter:class,new()
其中TForm:class,new()
{
_记录器=记录器;
TBusinessLogic businessLogic=新建BusinessLogicBuilder().Build();
TPresenter presenter=新的TPresenter(业务逻辑);
TForm form=新的TForm(演示者);
}
}

我需要向TPresenter和TForm传递一个参数。我可以这样做吗?如果是,如何实现这一点?

这里的问题是new()泛型约束仅确保类型具有默认的无参数构造函数。所以您的泛型类型不知道它们支持接受参数的构造函数


您可以确保您的类型实现一个接口,允许您调用属性或方法,例如Init(xxx),允许您在构造之后传入初始参数,而不是传入构造函数参数。例如,可以有一个名为iInitializable的参数。然后将其作为类型的类型约束

简单的回答是,仅使用一般约束无法做到这一点。C#语言中没有表示“类型必须有一个带有X类型参数的构造函数”的通用常量

这意味着您不能使用
newtform(presenter)
创建
TForm
类的对象

但是——这是个好消息——仍然可以使用反射:

var type = typeof(TPresenter);
var constructor = type.GetConstructors()
                      .FirstOrDefault(c => 
                          (c.GetParameters().Count() == 1) &&
                          (c.GetParameters()[0].ParameterType == typeof(TBusinessLogic)));

if (constructor == null)
{
    throw new SomeException();
}

TPresenter presenter = (TPresenter)constructor.Invoke(
    new object[]{ businessLogic });

对于TPresenter和TForm,您可以将where TPresenter:class,new()替换为包含参数化构造函数的实际实现或抽象类,如下所示

     public void Build<TBusinessLogic, TPresenter, TForm>(ILog logger)
        where TPresenter : PresenterClass, new()
            where TForm : FormClass, new()
    {
        _logger = logger;
        TBusinessLogic businessLogic = new BusinessLogicBuilder().Build<TBusinessLogic>();
        TPresenter presenter = new TPresenter(10);
                TForm form = new TForm(20);
    } 

    public abstract class PresenterClass
    {
        public PresenterClass(int parm)
        {
        }
    }

    public abstract class FormClass
    {
        public FormClass(int parm)
        {
        }
    }
公共无效生成(ILog记录器)
其中TPresenter:PresenterClass,new()
其中TForm:FormClass,new()
{
_记录器=记录器;
TBusinessLogic businessLogic=新建BusinessLogicBuilder().Build();
TPresenter presenter=新的TPresenter(10);
t形式=新的t形式(20);
} 
公共抽象类PresenterClass
{
公共演讲者课堂(国际标准)
{
}
}
公共抽象类FormClass
{
公共表单类(int parm)
{
}
}

这不起作用。仅仅因为基类有一个带1个参数的构造函数,并不意味着具体类也有相同的构造函数。