【问题标题】:What does "The type T must be a reference type in order to use it as parameter" mean?“类型 T 必须是引用类型才能将其用作参数”是什么意思?
【发布时间】:2016-07-20 13:44:02
【问题描述】:

我正在尝试在我的 C#/MVC/Entity Framework 应用程序上创建一个通用控制器。

public class GenericRecordController<T> : Controller
{
    private DbSet<T> Table;
    // ... 

    public action()
    {
        // ... 
        db.Entry(T_Instance).State = System.Data.Entity.EntityState.Modified;
    }
}

但是DbSet&lt;T&gt;T_Instance 行存在编译器错误。

类型 T 必须是引用类型才能用作参数。

当我将它限制为class 时,它就解决了。

Controller where T : class

错误是什么意思?我不是在寻求解决方案,我想了解为什么会发生此错误以及为什么将其限制为 class 可以解决它。

【问题讨论】:

  • 不完整且不清楚。此外,这是一个值得商榷的设计选择。
  • @HenkHolterman 。为什么选择糟糕的设计?
  • 它使您的控制器面向模型,它们应该面向视图。对 CRUD 来说是不必要的,对所有其他目的都是有害的。
  • T_Instance 从何而来?为什么它与 T 不同?
  • 我明白了。这个类是一个父类,只有一些通用方法(列表、删除等)。我的其他控制器类将从这个父类继承。 “class CustomerController : GenericController ...” 所以,我不认为这是一个糟糕的设计。只是避免一些重复的代码。感谢您的建议@HenkHolterman

标签: c# generics controller


【解决方案1】:

如果你看DbSet&lt;TEntity&gt;的定义:

public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable, IInternalSetAdapter 
where TEntity : class

因为它有一个type constraint,泛型类型必须是class,所以你必须用一个也符合这个条件的类型来初始化它:

public class GenericRecordController<T> : Controller where T : class
{ ... }

【讨论】:

    【解决方案2】:

    它们显然对泛型类型有限制。

    你需要改变的是:

    public class GenericRecordController<T> : Controller where T : class
    

    这告诉编译器只能提供引用类型作为 T 的类型。

    【讨论】:

      【解决方案3】:

      你也可以只用一个方法来做:

      public bool HasKey<T>(T obj) where T : class
      {
          return _db.Entry<T>(obj).IsKeySet;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多