为什么密封类不允许是泛型类型参数?

时间:2014-01-20 10:24:40

标签: c# .net generics

我有:

public abstract class DbManager<ConnectionType>
    where ConnectionType : class, IDbConnection, new() {...}

现在我分别有:

public class Db2Manager : DbManager<iDB2Connection>      // OK, NO problem
public class OleDbManager : DbManager<OleDbConnection>   // OK, NO problem
public class SqlServerManager : DbManager<SqlConnection> // OK, NO problem
public class SsasManager : DbManager<AdomdConnection>    // NOK, YES, a PROBLEM!

为什么这样? 因为在命名空间Microsoft.AnalysisServices.AdomdClient中我们有一个密封类:

// Assembly Microsoft.AnalysisServices.AdomdClient.dll, v2.0.50727
using System;
using System.ComponentModel;
using System.Data;

namespace Microsoft.AnalysisServices.AdomdClient
{
    public sealed class AdomdConnection : Component, IDbConnection, 
                                                     IDisposable, ICloneable
    {
        public AdomdConnection();

a)为什么限制使用密封类作为通用参数(!参数,而不是约束!)?
b)如何解决这个问题? c *)让这个课程密封是不是一个好主意?

PS。也许你有很多理由认为这个通用的DbManager不是一个好主意,但是,无论如何,我想了解是否有可能在泛型参数中解决这个密封的类...谢谢!

PPS。错误讯息:

  

'Microsoft.AnalysisServices.AdomdClient.AdomdConnection'必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法中的参数。

另一条错误消息指定:

  

“Microsoft.AnalysisServices.AdomdClient.AdomdConnection”类型   不能用作泛型类型或方法中的类型参数   是没有拳击转换或类型参数转换   'Microsoft.AnalysisServices.AdomdClient.AdomdConnection'到   'System.Data.IDbConnection'

AdomdConnection有一个无参数公共构造函数。

1 个答案:

答案 0 :(得分:2)

我相信密封课程没有这样的限制。下面的代码编译得很好,所以可能还有别的东西在继续。

public abstract class DbManager<T> where T : class, IDbConnection, new()
{
}

public class ConcreteDbManagerUsingSealedClass : DbManager<MySealedConnection>
{
}

public sealed class MySealedConnection : IDbConnection
{
    public IDbTransaction BeginTransaction(IsolationLevel il)
    {
        throw new NotImplementedException();
    }

    public IDbTransaction BeginTransaction()
    {
        throw new NotImplementedException();
    }

    public void ChangeDatabase(string databaseName)
    {
        throw new NotImplementedException();
    }

    public void Close()
    {
        throw new NotImplementedException();
    }

    public string ConnectionString
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public int ConnectionTimeout
    {
        get { throw new NotImplementedException(); }
    }

    public IDbCommand CreateCommand()
    {
        throw new NotImplementedException();
    }

    public string Database
    {
        get { throw new NotImplementedException(); }
    }

    public void Open()
    {
        throw new NotImplementedException();
    }

    public ConnectionState State
    {
        get { throw new NotImplementedException(); }
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}