我正在使用.net 1.1。我有一个会话类,我在其中存储了许多静态变量,这些变量包含许多类要使用的数据。
我想找到一种简单的方法来销毁这个类,而不是逐个重置每个变量。例如,如果有一个静态类MyStatic,我本来希望通过写MyStatic = null来破坏/删除这个类,这是目前无法实现的,
单身人士的想法很好,但我有以下问题:
如果实现单例,“单个”对象仍将保留在内存中。在单例中,我们只检查实例是否已存在。我怎样才能确保此实例变量也被破坏。
我有一个主类,用于初始化静态类中的变量。即使我计划实现Rest()方法,我也需要从一个方法中调用它,例如,主类中的析构函数。但是只有当GC在内存中收集这个主类对象时才会调用此析构函数,这意味着Reset()被调用很晚
感谢 普拉迪普
答案 0 :(得分:18)
不要使用静态类来存储变量。使用一个实例(如果你在任何给定的时间只想要一个实例,那就使它成为单例。)然后你可以实现IDisposible,并在你想要销毁它时调用Dispose()。
有关详细信息,请查看此网站:http://csharpindepth.com/Articles/General/Singleton.aspx
编辑
该对象仍然需要进行垃圾回收,因此除非您使用大量非托管资源,否则您应该没问题。您可以实现IDisposible来清理任何需要清理的资源。
答案 1 :(得分:9)
而不是静态类,有一个类的静态实例:
class Foo
{
public int Something;
public static Foo Instance = new Foo();
public void Reset()
{
Instance = new Foo();
}
}
void test
{
int i = Foo.Instance.Something;
}
您也可以委托给该类的实例:
class Foo
{
public int Something
{
get { return instance.something; }
}
private int something;
private static Foo instance = new Foo();
public void Reset()
{
instance = new Foo();
}
}
void test
{
int i = Foo.Something;
}
答案 2 :(得分:6)
除非它驻留在单独的AppDomain中,否则无法销毁静态,在这种情况下,您可以通过卸载AppDomain来消除静态。然而,通常最好避免使用静力学。
编辑:补充问题
当不再引用单身时,它将像其他一样被收集。换句话说,如果你想收集它,你必须确保没有对它的引用。不言而喻,如果您将静态引用存储到您的单例中,您将遇到与以前相同的问题。
答案 3 :(得分:2)
使用像ktrauberman这样的Singleton,并且有一个初始化方法或一个重置方法。您只需编写一次代码并调用该方法。
答案 4 :(得分:2)
你破坏对象,而不是类。静态类没有任何问题--C#提供它们是有原因的。单身人士只是额外的开销,除非你真的需要一个对象,例如当你必须将对象作为参数传递时。
静态类仅包含静态变量。这些变量往往会持续应用程序的生命周期,在这种情况下,您不必担心处置引用的对象,除非您有一个温和的OCD案例。这就是静态类在其生命周期中分配和释放资源的情况。像往常一样在适当的时候处理这些物体(例如,“使用......”)。
答案 5 :(得分:1)
你的条件最好的方法是内置一个Reset()方法,它可以重置类的值。
答案 6 :(得分:1)
class myclass
{
private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
singleobj = new myclass();
return singleobj
}
}
答案 7 :(得分:1)
以Ahemd Said的答案为基础:(并向他道具!)
class Singleton
{
private static Singleton instance = null;
private Singleton(){} // private constructor: stops others from using
public static Singleton Instance
{
get { return instance ?? (instance = new Singleton()); }
set {
if (null != value)
{ throw new InvalidValueException(); }
else
{ instance = null; }
}
}
}
void SampleUsage()
{
Singleton myObj = Singleton.Instance;
// use myObj for your work...
myObj.Instance = null; // The set-operator makes it ready for GC
}
(未经测试......但大多数是正确的,我认为) 您还可以添加IDispose接口的使用以进行更多清理。
答案 8 :(得分:0)
您可以在静态类中创建一个方法,该方法会重置所有属性的值。 考虑你有一个静态类
public static class ClassA
{
public static int id=0;
public static string name="";
public static void ResetValues()
{
// Here you want to reset to the old initialized value
id=0;
name="";
}
}
现在,您可以使用任何其他类中的任何一种方法来重置静态类的值
方法1 - 直接致电
ClassA.ResetValues();
方法2 - 从已知的命名空间和已知类
动态调用方法Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
方法3 - 从一个程序集/一组程序集动态调用方法
foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
{
// Use the above "If" condition if you want to filter from only one Dll
if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
{
List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
foreach (Type type in lstClasses)
{
MethodInfo methodInfo = type.GetMethod("ResetValues");
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(null, null);
}
}
break;
}
}
答案 9 :(得分:0)
在启动时从实现IDisposable的非静态类中将对象注入静态类,然后在非静态类被销毁时,静态类使用的对象也是如此。
确保实现类似“Disable()”的内容,以便让静态类知道它的对象刚被设置为null。
例如,我有一个记录器类,如下所示:
public static class Logger
{
private static Action<string, Exception, bool> _logError;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError != null) _logError = logError;
}
public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
{
_logError?.Invoke(msg, e, sendEmailReport);
}
在我的Form的构造函数中,我调用以下内容来设置记录器。
Logger.InitLogger(LogError);
然后从我项目的任何课程中我都可以做到以下几点:
Logger.LogError("error",new Exception("error), true);