【问题标题】:How to call parameterfull constructor of argument-type in C#? [duplicate]如何在 C# 中调用参数类型的参数构造函数? [复制]
【发布时间】:2020-09-24 13:04:30
【问题描述】:

我有一个带有全参数构造函数的抽象类:

public abstract class LoggerAdapterBase<TLogger>
{
    protected readonly TLogger _logger;

    public LoggerAdapterBase(TLogger logger){
        this._logger = logger;
    }
}

在其他类中,我必须创建实现抽象的具体类,但有一个问题:

public class LoggerManager<TLogger, TLoggerAdapter>: ILoggerManager<TLogger> where TLoggerAdapter: LoggerAdapterBase<TLogger>
{
    private readonly TLogger _logger;
    public LoggerManager(TLogger logger)
    {
        this._logger = logger;
    }
    public LoggerAdapterBase<TLogger> CreateLogger(Configuration configuration)
    {
        return new TLoggerAdapter(this._logger);
        //Line above says: Cannot create an instance of the variable type 'TLoggerAdapter' because it does not have the new() constraint
    }
}

我不知道为什么编译器需要 new() 约束,因为 LoggerAdapterBase 有一个我使用的构造函数,并且我已经将它指定给约束,它应该看到构造函数以及来自 LoggerAdapterBase 的其他方法。这里有什么问题?

编辑

谢谢你的回答,我已经解决了。我只是制作了接口而不是抽象类并定义了道具 Logger。并添加了约束 new()。现在创建看起来是这样的:

return new TLoggerAdapter() { Logger = _logger };

这不是一个理想的实现,因为从 LoggerManager 创建实例时可能会出现 NullReferenceExceptions,并且意外替换了 prop Logger。

【问题讨论】:

  • C# 类不从其基类继承构造函数。子类可以从自己的构造函数中调用父类的构造函数,但是父类的构造函数不能用来创建子类的实例。

标签: c# .net generics constructor constraints


【解决方案1】:

基本上,你不能做你想做的事。下面是一个例子:

// This is perfectly valid
public class StringLoggerAdapter : LoggerAdapterBase<string>
{
    private StringLoggerAdapter() : base("anything")
    {
    }
}

您希望LoggerManager&lt;string, StringLoggerAdapter&gt;.CreateLogger 做什么?它没有可访问的构造函数来调用, 存在的构造函数没有LoggerManager 期望的参数列表。

构造函数不会被继承——仅仅因为基类有一个带有特定参数列表的构造函数并不意味着派生类可以。

目前,除了需要无参数构造函数的new() 约束之外,没有办法要求类型参数具有特定的参数列表。

有人建议 C# 团队可能在更高版本的 C# 中引入此功能,但现在不存在,我不希望它出现在 C# 9 中。 p>

【讨论】:

    猜你喜欢
    • 2017-08-17
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 2017-05-19
    • 2017-12-31
    • 2011-09-25
    • 2016-03-26
    相关资源
    最近更新 更多