Asp.net mvc 是否将泛型类型参数声明为具有析构函数?

Asp.net mvc 是否将泛型类型参数声明为具有析构函数?,asp.net-mvc,entity-framework,generics,ef-code-first,destructor,Asp.net Mvc,Entity Framework,Generics,Ef Code First,Destructor,我有一个泛型类,它的开头是: public class EntityContextFactory<T> where T: class, IDisposable, IObjectContextAdapter, new() 我从ReSharper得到一个警告,说GC.SuppressFinalize是在没有析构函数的类型上调用的。如何删除此错误?我知道Dbcontexts确实有一个析构函数,因为当我非泛型地编写这种类型的类时,我没有得到这样的错误。我试图声明T实现了与Dbcon

我有一个泛型类,它的开头是:

public class EntityContextFactory<T>
    where T: class, IDisposable, IObjectContextAdapter, new()
我从ReSharper得到一个警告,说
GC.SuppressFinalize
是在没有析构函数的类型上调用的。如何删除此错误?我知道Dbcontexts确实有一个析构函数,因为当我非泛型地编写这种类型的类时,我没有得到这样的错误。我试图声明T实现了与Dbcontext相同的接口,但这似乎不起作用…

Description 我不确定您是否需要
GC.SuppressFinalize
。通常,这将用于非托管资源。垃圾收集器(GC)对没有
GC.SuppressFinalize
的托管资源执行此操作。
DbContext
是一个托管资源,您应该
Dispose()
而不是调用
GC.SuppressFinalize

您应该通过将对象的作用域限制为受保护,防止应用程序的用户直接调用对象的Finalize方法

你可以阅读和阅读

更多信息
说明 我不确定您是否需要
GC.SuppressFinalize
。通常,这将用于非托管资源。垃圾收集器(GC)对没有
GC.SuppressFinalize
的托管资源执行此操作。
DbContext
是一个托管资源,您应该
Dispose()
而不是调用
GC.SuppressFinalize

您应该通过将对象的作用域限制为受保护,防止应用程序的用户直接调用对象的Finalize方法

你可以阅读和阅读

更多信息

您可以通过不调用
SuppressFinalize
来删除此错误。没有通用约束(可能也没有ReSharper约束)可以应用于需要终结器的情况


任何具有终结器的类都应该调用
GC.SuppressFinalize(this)在其
Dispose
中。如果类没有这样做,它可能有一个很好的理由,您也不应该调用它。

您可以通过不调用
SuppressFinalize
来删除此错误。没有通用约束(可能也没有ReSharper约束)可以应用于需要终结器的情况


任何具有终结器的类都应该调用
GC.SuppressFinalize(this)在其
Dispose
中。如果类没有这样做,它可能有一个很好的理由,您也不应该调用它。

首先,
GC.SuppressFinalize(obj)
检查给定的引用是否等于直接调用方法的this指针(请参阅联机帮助:“obj参数必须是此方法的调用方”) -因此,除了
GC.SuppressFinalize(this)
之外的任何调用都将抛出异常

其次,调用
GC.SuppressFinalize(this)
表示GC不运行终结代码(实例从终结队列中删除)。终结队列越短,垃圾回收器运行越快。。。但由于所有对象都继承了终结器

第三,调用
GC.SuppressFinalize(this)
将有效地防止任何析构函数运行。我个人认为析构函数是代码气味!编写正确的终结器代码绝非易事(请记住,所有引用都可能已被释放)。除此之外,处理非托管资源应该正确实现
IDisposable
,并在收集对象之前调用
Dispose()
。拥有终结器只是最后一道防线——当没有人调用
Dispose()
时。通常应该使用像
using()
-这样的结构,它将负责调用
Dispose()

有关该主题的详细说明,请参见

那么-打电话-如果-在哪里打电话? 如果不处理非托管资源,因此没有析构函数,则进行调用。公共位置位于
Dispose()
-但这不是必需的。我的另一个最爱是.ctor()-尽管
这个
引用还没有完全构造好


重拾器警告在这里有点误导。它出现在两种情况下-当参数不是调用方时,以及当调用不在
Dispose()
中时。在您的特定情况下,不应进行调用。

首先,
GC.SuppressFinalize(obj)
检查给定引用是否等于直接调用方法的this指针(请参阅联机帮助:“obj参数必须是此方法的调用方。”) -因此,除了
GC.SuppressFinalize(this)
之外的任何调用都将抛出异常

其次,调用
GC.SuppressFinalize(this)
表示GC不运行终结代码(实例从终结队列中删除)。终结队列越短,垃圾回收器运行越快。。。但由于所有对象都继承了终结器

第三,调用
GC.SuppressFinalize(this)
将有效地防止任何析构函数运行。我个人认为析构函数是代码气味!编写正确的终结器代码绝非易事(请记住,所有引用都可能已被释放)。除此之外,处理非托管资源应该正确实现
IDisposable
,并在收集对象之前调用
Dispose()
。拥有终结器只是最后一道防线——当没有人调用
Dispose()
时。通常应该使用像
using()
-这样的结构,它将负责调用
Dispose()

有关该主题的详细说明,请参见

那么-打电话-如果-在哪里打电话? 如果不处理非托管资源,因此没有析构函数,则进行调用。常见的地方是在
Dispose()
-但那是
            T context = HttpContext.Current.Items[objectContextKey] as T;
            if (context != null)
            {
                context.Dispose();
                GC.SuppressFinalize(context);
                HttpContext.Current.Items.Remove(objectContextKey);
            }