翻蚳è ãã
ã¡ã¢ãªãªãŒã¯ãšã€ãã³ãã®æ£ããå®è£ ã«ã€ããŠã®è©±ã®åŸãã¡ã¢ãªç®¡çã®ãããã¯ã§æ°ã«å ¥ã£ãèšäºã®å¥ã®ç¿»èš³ãæçš¿ããŸãã Disposeãã¿ãŒã³ã®ããã€ãã®ç°ãªãå®è£ ã確èªããŸããããæã«ã¯äºãã«ççŸããããšãããããŸããã ãã®èšäºã§ã¯ãèè ã¯IDisposableã€ã³ã¿ãŒãã§ã€ã¹ããã€å®è£ ãããããã€ãã¡ã€ãã©ã€ã¶ãŒã䜿çšãããããã€-äžç·ã«äœ¿çšãããã«ã€ããŠãæ確ã§æ確ãªèª¬æãæäŸããŸããã
IDisposableãšãã¡ã€ãã©ã€ã¶ãŒãé©çšããæ¹æ³ïŒ3ã€ã®ç°¡åãªã«ãŒã«
IDisposableã®äœ¿çšã«é¢ããMicrosoftã®ããã¥ã¡ã³ãã¯ããªããããã«ããã§ãã å®éã3ã€ã®åçŽãªã«ãŒã«ã«åçŽåãããŠããŸãã
ã«ãŒã«1ïŒé©çšããªãïŒæ¬åœã«å¿ èŠã«ãªããŸã§ïŒ
IDisposableã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããããšã«ããããã¹ãã©ã¯ã¿ãäœæããŠããŸããã .NETç°å¢ã«ã¯ãè€æ°ã®å€æ°ãnullã«ããªãããã«ååã«æ©èœããã¬ããŒãžã³ã¬ã¯ã¿ãŒããããŸãã
IDisposableãå®è£ ããå¿ èŠãããç¶æ³ã¯2ã€ã ãã§ãã ã¯ã©ã¹ãèŠãŠããã®ã€ã³ã¿ãŒãã§ã€ã¹ãå¿ èŠãã©ãããå€æããŸãã
- ã¯ã©ã¹ã«ã¢ã³ãããŒãžãªãœãŒã¹ããããŸã
- ã¯ã©ã¹ã¯ïŒIDisposableïŒãªãœãŒã¹ã管çããŠããŸã
ãªãœãŒã¹ã¯ããããã®ãªãœãŒã¹ãå±ããã¯ã©ã¹ã®ã¿ã解æŸããå¿ èŠãããããšã«æ³šæããŠãã ããã ç¹ã«ãã¯ã©ã¹ã¯å ±æãªãœãŒã¹ãžã®ãªã³ã¯ãæã£ãŠããå¯èœæ§ããããŸã-ãã®å Žåãä»ã®ã¯ã©ã¹ããã®ãªãœãŒã¹ã䜿çšãç¶ããå¯èœæ§ãããããããã®ãªãœãŒã¹ã解æŸããªãã§ãã ããã
å€ãã®åå¿è ããã°ã©ããŒãæžãã³ãŒãã®äŸã次ã«ç€ºããŸãã
// IDisposable. public sealed class ErrorList : IDisposable { private string category; private List<string> errors; public ErrorList(string category) { this.category = category; this.errors = new List<string>(); } // ( / ) // public void Dispose() { if (this.errors != null) { this.errors.Clear(); this.errors = null; } } }
äžéšã®ããã°ã©ããŒïŒç¹ã«ä»¥åã«C ++ã§äœæ¥ããããšã®ããããã°ã©ããŒïŒã¯ãããã«é²ãã§ãã¡ã€ãã©ã€ã¶ãŒãè¿œå ããŸãã
// IDisposable. public sealed class ErrorList : IDisposable { private string category; private List<string> errors; public ErrorList(string category) { this.category = category; this.errors = new List<string>(); } // ( / ) // public void Dispose() { if (this.errors != null) { this.errors.Clear(); this.errors = null; } } ~ErrorList() { // !</font> // !</font> this.Dispose(); } }
äŸã¯ã説æããã¯ã©ã¹ã®IDisposableã®æ£ããå®è£ ã§ãã
// IDisposable. public sealed class ErrorList { private string category; private List<string> errors; public ErrorList(string category) { this.category = category; this.errors = new List<string>(); } }
ããã£ãã ãã®ã¯ã©ã¹ã®IDisposableã€ã³ã¿ãŒãã§ã€ã¹ã®é©åãªäœ¿çš-é©çšããªãã§ãã ããïŒ ErrorListã€ã³ã¹ã¿ã³ã¹ã䜿çšã§ããªããªããšãã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯äœ¿çšäžã®ã¡ã¢ãªãèªåçã«è§£æŸããŸãã
IDisposableãé©çšããããã®ããã2ã€ã®åºæºãèŠããŠãããŠãã ãã-ã¯ã©ã¹ã¯ã¢ã³ãããŒãžãŸãã¯ãããŒãžãªãœãŒã¹ãææããå¿ èŠããããŸãã ããªãã¯ãã€ã³ããééããããšãã§ããŸãïŒ
1. ErrorListã¯ã©ã¹ã¯ã¢ã³ãããŒãžãªãœãŒã¹ãææããŠããŸããïŒ ããããææããŠããŸããã
2. ErrorListã¯ã©ã¹ã«ã¯ç®¡ç察象ãªãœãŒã¹ããããŸããïŒ ããããŒãžãªãœãŒã¹ãã¯IDisposableãå®è£ ããã¯ã©ã¹ã§ããããšã«æ³šæããŠãã ããã ã¯ã©ã¹ã®åã¡ã³ããŒã確èªããŸãã
1.æååã¯ã©ã¹ã¯IDisposableãå®è£ ããŠããŸããïŒ ããããããã§ã¯ãããŸããã
2. Listã¯ã©ã¹ã¯IDisposableãå®è£ ããŠããŸããïŒ ããããããã§ã¯ãããŸããã
3. IDisposableãå®è£ ããŠããã¡ã³ããŒãããªãå ŽåãErrorListã¯ã©ã¹ã¯ç®¡ç察象ãªãœãŒã¹ãææããŠããŸããã
3. ErrorListã¯ãããŒãžãªãœãŒã¹ãã¢ã³ãããŒãžãªãœãŒã¹ãææããªããããIDisposableã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£ ã¯å¿ èŠãããŸããã
ã«ãŒã«2ïŒç®¡ç察象ãªãœãŒã¹ãææããã¯ã©ã¹ã®å ŽåãIDisposableãå®è£ ããŸãïŒãã¡ã€ãã©ã€ã¶ãŒã¯å®è£ ããŸããïŒ
IDisposableã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯ãDisposeãšãã1ã€ã®ã¡ãœããã®ã¿ããããŸãã ãã®ã¡ãœãããå®è£ ããå Žåã1ã€ã®éèŠãªçŸ©åãæããå¿ èŠããããŸããDisposeãžã®è€æ°ã®åŒã³åºãã§ããšã©ãŒãªãã§çºçããå¿ èŠããããŸãã
Disposeã¡ãœããã®å®è£ ã¯ããã®ã¡ãœããããã¡ã€ãã©ã€ã¶ãŒã¹ã¬ããããåŒã³åºãããŠããªãããšããªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãã£ãŠãŸã åéãããŠããªãããšãããã³ãªããžã§ã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒãæ£åžžã«å®äºããããšãæå³ããŸãã ãããã®åæã«ããã管ç察象ãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãå®å šã«ãªããŸãã
管ç察象ãªãœãŒã¹ã®ã¿ãææããã¯ã©ã¹ã«ãã¡ã€ãã©ã€ã¶ãŒãé 眮ãããšããšã©ãŒãçºçããå¯èœæ§ããããŸãã ãã®ãµã³ãã«ã³ãŒãã¯ããã¡ã€ãã©ã€ã¶ãŒã¹ã¬ããã§äŸå€ãã¹ããŒããã¢ããªã±ãŒã·ã§ã³ãäžæããå¯èœæ§ããããŸãã
// . public sealed class SingleApplicationInstance { private Mutex namedMutex; private bool namedMutexCreatedNew; public SingleApplicationInstance(string applicationName) { this.namedMutex = new Mutex(false, applicationName, out namedMutexCreatedNew); } public bool AlreadyExisted { get { return !this.namedMutexCreatedNew; } } ~SingleApplicationInstance() { // , , !!! this.namedMutex.Close(); } }
SingleApplicationInstanceãIDisposableã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããã©ããã¯åé¡ã§ã¯ãããŸããããã¡ã€ãã©ã€ã¶ã§ç®¡ç察象ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ãããšããäºå®ã¯ããšã©ãŒã«å¯Ÿããæ£ããæ¹æ³ã§ãã
ãã¡ã€ãã©ã€ã¶ããªããIDisposableã€ã³ã¿ãŒãã§ã€ã¹ãæ£ããããããè€éãããæ¹æ³ã§å®è£ ãããŠããã¯ã©ã¹ã®äŸã次ã«ç€ºããŸãã
// IDisposable. public sealed class SingleApplicationInstance : IDisposable { private Mutex namedMutex; private bool namedMutexCreatedNew; public SingleApplicationInstance(string applicationName) { this.namedMutex = new Mutex(false, applicationName, out namedMutexCreatedNew); } public bool AlreadyExisted { get { return !this.namedMutexCreatedNew; } } // public void Dispose() { if (namedMutex != null) { namedMutex.Close(); namedMutex = null; } } }
ã¯ã©ã¹ã管ç察象ãªãœãŒã¹ãææããŠããå Žåããã®ã¯ã©ã¹ã§Disposeã¡ãœãããåŒã³åºãããšãã§ããŸãã è¿œå ã®ã³ãŒãã¯å¿ èŠãããŸããã äžéšã®ã¯ã©ã¹ã§ã¯ãDisposeãã®ååããCloseãã«å€æŽããŠãããããDisposeã¡ãœããã®å®è£ ã¯ãDisposeããã³Closeã¡ãœããã®åŒã³åºãã®ã¿ã§æ§æãããŠããå Žåãããããšã«æ³šæããŠãã ããã
åçã§ç°¡åãªå®è£ ïŒ
// IDisposable. public sealed class SingleApplicationInstance : IDisposable { private Mutex namedMutex; private bool namedMutexCreatedNew; public SingleApplicationInstance(string applicationName) { this.namedMutex = new Mutex(false, applicationName, out namedMutexCreatedNew); } public bool AlreadyExisted { get { return !this.namedMutexCreatedNew; } } public void Dispose() { namedMutex.Close(); } }
Disposeã¡ãœããã®ãã®å®è£ ã¯å®å šã«å®å šã§ãã IDisposableåãªãœãŒã¹ã®åå®è£ ã¯é çªã«å®å šã§ãããããå¿ èŠã«å¿ããŠäœåºŠã§ãåŒã³åºãããšãã§ããŸãã ãã®æšç§»çãªããããã£ã䜿çšããŠãDisposeã¡ãœããã®ãã®ãããªåçŽãªå®è£ ãèšè¿°ããå¿ èŠããããŸãã
ã«ãŒã«3ïŒç®¡çãããŠããªããªãœãŒã¹ãææããã¯ã©ã¹ã®å ŽåãIDisposableãšãã¡ã€ãã©ã€ã¶ãŒãå®è£ ããŸã
管çãããŠããªããªãœãŒã¹ã1ã€ææããã¯ã©ã¹ã¯ãä»ã®ããšãäžåè¡ãã¹ãã§ã¯ãããŸããã 圌ã®å¯äžã®çŸ©åã¯ããã®ãªãœãŒã¹ãéããããšã§ãã
ã¯ã©ã¹ã¯ãããã€ãã®ã¢ã³ãããŒãžãªãœãŒã¹ãæ åœããã¹ãã§ã¯ãããŸããã 1ã€ã®ãªãœãŒã¹ãæ£ãã解æŸããããšã¯éåžžã«é£ãããè€æ°ã®ç®¡çãããŠããªããªãœãŒã¹ãå«ãã¯ã©ã¹ãèšè¿°ããããšã¯ããã«å°é£ã§ãã
ã¯ã©ã¹ã¯ã管çããããªãœãŒã¹ãšç®¡çãããŠããªããªãœãŒã¹ãäžç·ã«æ±ãã¹ãã§ã¯ãããŸããã ãã®ãããªã¯ã©ã¹ãäœæããããšã¯å¯èœã§ãããæ£ããè¡ãããšã¯éåžžã«å°é£ã§ãã ç§ãä¿¡ã㊠ããè¯ããšããããšããªãã§ãã ããã ã¯ã©ã¹ã«ãšã©ãŒããªããŠããã¡ã³ããã³ã¹ã¯æªå€¢ã«å€ãããŸãã .NET 2.0ãç»å ŽãããŸã§ã«ãMicrosoftã¯BCLïŒåºæ¬ã¯ã©ã¹ã©ã€ãã©ãªïŒããå€ãã®ã¯ã©ã¹ãæžãçŽããããããã¢ã³ãããŒãžãªãœãŒã¹ãšãããŒãžãªãœãŒã¹ãææããã¯ã©ã¹ã«åå²ããŸããã
泚ïŒIDisposableã«é¢ãããã®ãããªè€éãªå ¬åŒããã¥ã¡ã³ãã®ååšã¯ãMicrosoftãã¯ã©ã¹ã«äž¡æ¹ã®ã¿ã€ãã®ãªãœãŒã¹ãå«ãŸãããšä¿¡ããŠãããšããäºå®ã«ãããã®ã§ãã ããã¯ãäžäœäºææ§ã®ããã«æ®ããã.NET 1.0ã®éºç©ã§ãã Microsoftã§äœæãããã¯ã©ã¹ã§ããããã®å€ããã¿ãŒã³ã«åŸããŸããïŒ.NET 2.0ã§ã¯ããã®èšäºã§èª¬æãããã¿ãŒã³ã䜿çšããŠå€æŽãããŸããïŒã FxCopã¯ã IDisposableããæ£ãããå®è£ ããå¿ èŠããããšèšããŸãïŒã€ãŸããå€ããã³ãã¬ãŒãã䜿çšããŸãïŒã 圌ã®èšãããšãèããªãã§ãã ãã-FxCopã¯ééã£ãŠããŸãã
ã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
// IDisposable. // SafeHandle. public sealed class WindowStationHandle : IDisposable { public WindowStationHandle(IntPtr handle) { this.Handle = handle; } public WindowStationHandle() : this(IntPtr.Zero) { } public bool IsInvalid { get { return (this.Handle == IntPtr.Zero); } } public IntPtr Handle { get; set; } private void CloseHandle() { // , if (this.IsInvalid) { return; } // , if (!NativeMethods.CloseWindowStation(this.Handle)) { Trace.WriteLine("CloseWindowStation: " + new Win32Exception().Message); } // this.Handle = IntPtr.Zero; } public void Dispose() { this.CloseHandle(); GC.SuppressFinalize(this); } ~WindowStationHandle() { this.CloseHandle(); } } internal static partial class NativeMethods { [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CloseWindowStation(IntPtr hWinSta); }
Disposeã¡ãœããã®æåŸã«ã GC.SuppressFinalizeïŒthisïŒã®åŒã³åºãããããŸãã ããã«ããããªããžã§ã¯ãã®ãã¡ã€ãã©ã€ã¶ãåŒã³åºãããªããªããŸãã
Disposeãæ瀺çã«åŒã³åºãããªãå Žåããã¡ã€ãã©ã€ã¶ã¯æçµçã«æ©èœãããã³ãã«ãéããŸãã
CloseHandleã¡ãœããã¯ãæåã«ãã³ãã«ãnullãã©ããã確èªããŸãã 次ã«ãå¯èœãªäŸå€ãã¹ããŒããã«éããŸãã CloseHandleã¯ãã¡ã€ãã©ã€ã¶ããåŒã³åºãããšãã§ããäŸå€ãã¹ããŒãããšããã»ã¹ãåæ¢ããŸãã CloseHandleã¡ãœããã¯ããã³ãã«ãnullã«ããããšã§çµäºããŸãã T.O. äœåºŠã§ãåŒã³åºãããšãã§ããŸãã ããã«ãããDisposeãç¹°ãè¿ãåŒã³åºãããšãå®å šã«ãªããŸãã Disposeã«ãã³ãã«ãã§ãã¯ãé 眮ã§ããŸããããã®ãã§ãã¯ãCloseHandleã«é 眮ãããšãnullãã³ãã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŠãããããHandleããããã£ã«å²ãåœãŠãããšãã§ããŸãã
CloseHandleã®åŸã«SuppressFinalizeãåŒã³åºãããçç±ã¯ããã³ãã«ãéãããšãã«Disposeã§ãšã©ãŒãçºçããå Žåããã¡ã€ãã©ã€ã¶ãŒãåŒã³åºãããããã§ãã ãã®çç±ã¯ãJoe Duffyã®ããã° ïŒ è©³çŽ° ã¯éåžžã«è¯ãèšäºã§ã-ãããPerã ïŒ ã§è©³çŽ°ã«è°è«ãããŸããããããªã匱ãè°è«ã§ããã éãã¯ãCloseHandleã¡ãœããããã¡ã€ãã©ã€ã¶ããåŒã³åºããããšãã«ç°ãªãæ¹æ³ã§ãã³ãã«ãéããå Žåã«ã®ã¿ååšããŸãã ãã¡ãããããã¯å®è¡ã§ããŸãããæšå¥šãããŸããã
éèŠïŒ WindowStationHandleã¯ã©ã¹ã«ã¯ãŠã£ã³ããŠã¬ã€ã¢ãŠããã³ãã«ãå«ãŸããŠãããããŠã£ã³ããŠã¬ã€ã¢ãŠãã®äœæãŸãã¯ãªãŒãã³ã«ã€ããŠã¯äœãç¥ããŸããã ãããã®é¢æ°ã¯ïŒãŠã£ã³ããŠã«é¢é£ããä»ã®é¢æ°ãšåæ§ã«ïŒå¥ã®ã¯ã©ã¹ïŒãããããWindowStationãïŒã®ã¿ã¹ã¯ã§ãã ããã«ãããæ£ããå®è£ ãäœæã§ããŸãã äŸå€ãã¹ããŒãããããããã¶ã€ããŒãäžå®å šãªæœèšã§ãåãã¡ã€ãã©ã€ã¶ãå®è¡ããå¿ èŠããããŸãã å®éã«ã¯ããããè¡ãã®ã¯é£ãããããããã©ãããŒã¯ã©ã¹ããã³ãã«ãéããã¯ã©ã¹ãšã©ãããŒã¯ã©ã¹èªäœã«åå²ããå¿ èŠããããã1ã€ã®çç±ã§ãã
泚ïŒäžèšã®ãœãªã¥ãŒã·ã§ã³ã¯æãåçŽã§ãããæ¬ ç¹ããããŸãã ããšãã°ããªãœãŒã¹å²ãåœãŠé¢æ°ãå®è¡ãããçŽåŸã«ã¹ã¬ãããçµäºãããšããã®ãªãœãŒã¹ããªãŒã¯ããå¯èœæ§ããããŸãã IntPtrãã³ãã«ãã©ããããå Žåã SafeHandleã¯ã©ã¹ããç¶æ¿ããã®ãæåã§ãã ããã«é²ãã§ããªãœãŒã¹ã®ä¿¡é Œã§ãããªãªãŒã¹ãç¶æããå¿ èŠãããå Žåããã¹ãŠãããã«éåžžã«æ··ä¹±ããŸã ïŒ å¥ã®è¯ãèšäº-çŽPerã ïŒïŒ