c# - 回归泛型类型

标签 c# generics casting

假设以下示例。数据库连接处理的通用方法。 DbConnection.BeginTransaction()(来自 System.Data.Common)返回一个 DbTransaction 实例。 既然已经明确说明了这一点,为什么我需要明确地强制转换它?

internal abstract class ADatabase<DbCommandType, DbConnectionType, DbTransactionType> : IDisposable
    where DbCommandType : DbCommand, new()
    where DbConnectionType : DbConnection, new()
    where DbTransactionType : DbTransaction, new()
{
    DbConnectionType _connection;
    DbTransactionType _transaction;

    void Foo()
    {
        _transaction = _connection.BeginTransaction(); // <-- Error..
    }
}

我遇到的错误是

Error 1 Cannot implicitly convert type 'System.Data.Common.DbTransaction' to 'DbTransactionType'. An explicit conversion exists (are you missing a cast?)

我当然可以施放它,但问题是为什么

最佳答案

您的泛型有一个约束,即 DbTransactionType 必须是类 DbTransaction 或从它派生的任何类

有了这个突出显示,就应该清楚您甚至不应该显式地强制转换它。

但是如果不清楚: BeginTransaction 的返回值是 DbTransaction 类型的实例。 _transaction 的类型是 DbTransactionType,它可以是 DbTransaction子类。如果不进行强制转换,则无法将基类的变量分配给子类的变量。并且只有当基类的变量实际上包含该子类的实例时,转换才会起作用。

在思考这个问题时,在您的心智模型中,将 DbTransactionType 替换为 string,将 DbTransaction 替换为 object。现在问题应该立即清楚了。

关于c# - 回归泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16896745/

相关文章:

c# - 返回空任务还是返回 null 更好? C#

java - 键入 DefaultListModel 以避免强制转换

python - ctypes 将 c_uint64 转换为 c_char_p

typescript - 如何在 typescript 中将枚举映射到另一个枚举?

c# - 我可以在 C# 中固定类型化 ArrayList,就像 C++ 一样吗?

c# - 无法使用 MSMQ 让 MassTransit 在 IIS Express 上工作

c# - 通用接口(interface)的嵌套契约

c# - 泛型类型推断在 C# 中如何工作?

java - corda实现通用vault查询

java - 强制子类重写以自身为参数的方法