ã¯ããã«
èªè ã¯CïŒã®ä»®æ³æ§ã®ã¡ã«ããºã ãããç¥ã£ãŠãããšæããŸãã ç解ããæãç°¡åãªæ¹æ³ã¯ãä»®æ³ã¡ãœããã®äŸã§ãã ãã®å Žåãä»®æ³æ§ã«ããããªããžã§ã¯ãã®ã©ã³ã¿ã€ã ã®ã¿ã€ãã«å¿ããŠãä»®æ³ã¡ãœããã®ãªãŒããŒã©ã€ãã®1ã€ãå®è¡ã§ããŸãã ãã®ã¡ã«ããºã ãç°¡åãªäŸã§èª¬æããŸãã
class A { public virtual void F() { Console.WriteLine("AF"); } public void G() { Console.WriteLine("AG"); } } class B : A { public override void F() { Console.WriteLine("BF"); } public new void G() { Console.WriteLine("BG"); } } static void Main(....) { B b = new B(); A a = b; aF(); bF(); aG(); bG(); }
å®è¡ã®çµæãã³ã³ãœãŒã«ã«ã¯ä»¥äžã衚瀺ãããŸãã
BF BF AG BG
ãã¹ãŠæ£ããã§ãã ãªããžã§ã¯ãaãšbã®äž¡æ¹ãå®è¡æå Bãæã£ãŠããããããããã®ãªããžã§ã¯ãã®äž¡æ¹ã«å¯ŸããŠä»®æ³ã¡ãœããFïŒïŒãåŒã³åºããšãã¯ã©ã¹Bã®ãªãŒããŒã©ã€ããããã¡ãœããFïŒïŒãåŒã³åºãããŸããäžæ¹ããªããžã§ã¯ãaãšbã¯ã³ã³ãã€ã«æã®åã«ãã£ãŠç°ãªããŸããããããã¿ã€ãAããã³Bãæã¡ãŸãã ãããã£ãŠããããã®åãªããžã§ã¯ãã®GïŒïŒã¡ãœãããåŒã³åºããšãã¯ã©ã¹AãŸãã¯Bã®å¯Ÿå¿ããã¡ãœãããåŒã³åºãããŸãã virtualããã³overrideããŒã¯ãŒãã®äœ¿çšæ¹æ³ã®è©³çŽ°ã«ã€ããŠã¯ãããšãã°ãã¡ããã芧ãã ãã ã
ã¡ãœãããããããã£ãã€ã³ãã¯ãµãŒãšåæ§ã«ã ã€ãã³ãã¯ä»®æ³ãšããŠå®£èšã§ããŸãã
public virtual event ....
ããã¯ããã·ã³ãã«ããªè¿œå ã€ãã³ããšåé€ã€ãã³ãã®æ瀺çãªå®è£ ã®äž¡æ¹ã§å®è¡ã§ããŸãã åæã«ãä»®æ³ã€ãã³ããæäœãã掟çã¯ã©ã¹ã§ãªãŒããŒã©ã€ããããå Žåãããšãã°ä»®æ³ã¡ãœããã«äŒŒãåäœããããããæåŸ ããããšã¯è«ççã§ãã ããããããã¯ããã§ã¯ãããŸããã ããã«ã MSDNã¯ä»®æ³ã€ãã³ãããã³ãªãŒããŒã©ã€ããããã€ãã³ãã®äœ¿çšãæ瀺çã«æšå¥šããŠããŸãã ããåºæ¬ã¯ã©ã¹ã§ä»®æ³ã€ãã³ãã宣èšãããã掟çã¯ã©ã¹ã§ãããããªãŒããŒã©ã€ããããããªãã§ãã ããã CïŒã³ã³ãã€ã©ã¯ããããæ£ããåŠçããã掟çã€ãã³ãã®ãµãã¹ã¯ã©ã€ããŒãå®éã«åºæ¬ã¯ã©ã¹ã€ãã³ãã«ãµãã¹ã¯ã©ã€ããããã©ããã¯äºæž¬ã§ããŸããã
ããããããã«giveããã«ãã...åºæ¬ã¯ã©ã¹ã§ä»®æ³ã€ãã³ãã宣èšãã掟çã¯ã©ã¹ã§ãããããªãŒããŒã©ã€ããããããšãå®è£ ããããšããŸãã
å®éš
æåã®å®éšãšããŠãåºæ¬ã¯ã©ã¹ã®2ã€ã®ä»®æ³ã€ãã³ãã®å®£èšãšäœ¿çšïŒ è¿œå ããã³åé€ã¢ã¯ã»ãµãŒã®æé»çããã³æ瀺çãªå®è£ ïŒãå«ã¿ããããã®ã€ãã³ãããªãŒããŒã©ã€ããã掟çã¯ã©ã¹ãå«ãã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
class Base { public virtual event Action MyEvent; public virtual event Action MyCustomEvent { add { _myCustomEvent += value; } remove { _myCustomEvent -= value; } } protected Action _myCustomEvent { get; set; } public void FooBase() { MyEvent?.Invoke(); _myCustomEvent?.Invoke(); } } class Child : Base { public override event Action MyEvent; public override event Action MyCustomEvent { add { _myCustomEvent += value; } remove { _myCustomEvent -= value; } } protected new Action _myCustomEvent { get; set; } public void FooChild() { MyEvent?.Invoke(); _myCustomEvent?.Invoke(); } } static void Main(...) { Child child = new Child(); child.MyEvent += () => Console.WriteLine("child.MyEvent handler"); child.MyCustomEvent += () => Console.WriteLine("child.MyCustomEvent handler"); child.FooChild(); child.FooBase(); }
ããã°ã©ã ã®çµæã¯ãã³ã³ãœãŒã«ã«2è¡åºåãããŸãã
child.MyEvent handler child.MyCustomEvent handler
ãããã¬ãŒãŸãã¯ãã¹ãåºåã䜿çšãããšã child.FooBaseïŒïŒã®åŒã³åºãæã«å€æ°MyEventãš_myCustomEventã®äž¡æ¹ã®å€ãnullã§ãããããã°ã©ã ãMyEventãããªã¬ãŒããããšãããšãã«æ¡ä»¶ä»ãã¢ã¯ã»ã¹æŒç®åã䜿çšããããšã«ãã£ãŠã®ã¿ãã¯ã©ãã·ã¥ãããªãããšãç°¡åã«ç¢ºèªã§ããŸããïŒ.InvokeïŒ ïŒããã³_myCustomEventïŒ.InvokeïŒïŒ ã
ãããã£ãŠãMSDNã®èŠåã¯ç¡é§ã§ã¯ãããŸããã§ããã ããã¯æ¬åœã«æ©èœããŸããïŒ æŽŸçã¯ã©ã¹Childã®ã©ã³ã¿ã€ã ã¿ã€ããæã€ãªããžã§ã¯ãã®ä»®æ³ã€ãã³ãããµãã¹ã¯ã©ã€ãããŠããBaseåºæ¬ã¯ã©ã¹ã®ã€ãã³ããåæã«ãµãã¹ã¯ã©ã€ãããããšã¯ã§ããŸããã
æé»çãªã€ãã³ãå®è£ ã®å Žåãã³ã³ãã€ã©ã¯ããµãã¹ã¯ã©ã€ããŸãã¯ãµãã¹ã¯ã©ã€ã解é€ã«äœ¿çšãããããªã²ãŒããã£ãŒã«ããšåæ§ã«ããã®ã¢ã¯ã»ãµã¡ãœãããèªåçã«è¿œå ããã³åé€ããŸãã åé¡ã¯ãæããã«ãä»®æ³ã€ãã³ãã䜿çšããå ŽåãããŒã¹ã¯ã©ã¹ãšåã¯ã©ã¹ã«ããã®ã€ãã³ãã«é¢é£ä»ããããåã ã®ïŒéä»®æ³ïŒããªã²ãŒããã£ãŒã«ããããããšã§ãã
æ瀺çãªå®è£ ã®å Žåãããã¯éçºè ã«ãã£ãŠè¡ãããéçºè ã¯CïŒã®ä»®æ³ã€ãã³ãã®åäœã®ãã®æ©èœãèæ ®ããããšãã§ããŸãã äžèšã®äŸã§ã¯ã _myCustomEventããªã²ãŒãããããã£ãåºæ¬ã¯ã©ã¹ãšæŽŸçã¯ã©ã¹ã§ä¿è·ãããŠãããšå®£èšããããšã§ããã®æ©èœãèæ ®ããŸããã§ããã ãããã£ãŠãå®éã«ã¯ã³ã³ãã€ã©ãŒã«ãã£ãŠæäŸãããå®è£ ãä»®æ³ã€ãã³ãã«å¯ŸããŠèªåçã«ç¹°ãè¿ããŸããã
ããã§ãã2çªç®ã®å®éšã䜿çšããŠãä»®æ³ã€ãã³ãã®äºæ³ãããåäœãéæããããšããŸãããã ãããè¡ãã«ã¯ã è¿œå ããã³åé€ã¢ã¯ã»ãµã®æ瀺çãªå®è£ ãšããããã«é¢é£ä»ããããä»®æ³ããªã²ãŒãããããã£ã䜿çšããŠãä»®æ³ããã³åå®çŸ©ãããã€ãã³ãã䜿çšããŸãã æåã®å®éšããããã°ã©ã ã®ããã¹ããå°ãå€æŽããŠã¿ãŸãããã
class Base { public virtual event Action MyEvent; public virtual event Action MyCustomEvent { add { _myCustomEvent += value; } remove { _myCustomEvent -= value; } } public virtual Action _myCustomEvent { get; set; } //<= virtual public void FooBase() { MyEvent?.Invoke(); _myCustomEvent?.Invoke(); } } class Child : Base { public override event Action MyEvent; public override event Action MyCustomEvent { add { _myCustomEvent += value; } remove { _myCustomEvent -= value; } } public override Action _myCustomEvent { get; set; } //<= override public void FooChild() { MyEvent?.Invoke(); _myCustomEvent?.Invoke(); } } static void Main(...) { Child child = new Child(); child.MyEvent += () => Console.WriteLine("child.MyEvent handler"); child.MyCustomEvent += () => Console.WriteLine("child.MyCustomEvent handler"); child.FooChild(); child.FooBase(); }
ããã°ã©ã ã®çµæïŒ
child.MyEvent handler child.MyCustomEvent handler child.MyCustomEvent handler
child.MyCustomEventã€ãã³ãã«å¯ŸããŠ2ã€ã®ãã³ãã©ãŒã€ãã³ããçºçããããšã«æ³šæããŠãã ããã ãããã°ã¢ãŒãã§ã¯ã FooBaseïŒïŒã¡ãœããã§_myCustomEventïŒ.InvokeïŒïŒãåŒã³åºããšãã«ã _myCustomEventã®ããªã²ãŒãå€ãnull㧠ã¯ãªãããšãç°¡åã«å€æã§ããŸã ã ãããã£ãŠãæ瀺çã«å®è£ ãããè¿œå ã¢ã¯ã»ãµãŒãšåé€ã¢ã¯ã»ãµãŒãæã€ã€ãã³ãã䜿çšããããšã«ãã£ãŠã®ã¿ãä»®æ³ã€ãã³ãã«æåŸ ãããåäœãéæããããšãã§ããŸããã
ãã¡ãããããã¯ãã¹ãŠè¯ããšèšããŸãããçè«åéããã®ããçš®ã®åæäŸã«ã€ããŠè©±ãããããã®ä»®æ³ã€ãã³ããšåå®çŸ©ãããã€ãã³ããããã«æ®ãããã«ããŸãã ç§ã¯æ¬¡ã®ã³ã¡ã³ããããŸãïŒ
- ä»®æ³ã€ãã³ãã䜿çšããããåŸãªãç¶æ³ã«é¥ãããšããããŸãã ããšãã°ãæé»çãªå®è£
ãæã€æœè±¡ã€ãã³ãã宣èšãããŠããæœè±¡ã¯ã©ã¹ããç¶æ¿ããŸãã ãã®çµæã䜿çšããŠããå¯èœæ§ã®ããã¯ã©ã¹ã§ãªãŒããŒã©ã€ããããã€ãã³ããåãåããŸãã ã¯ã©ã¹ããç¶æ¿ããŠãã®ã€ãã³ããåå®çŸ©ããããšã決å®ãããŸã§ãããã«ã¯å±éºã¯ãããŸããã
- ãã®ãããªãã¶ã€ã³ã¯ãŸãã§ãããå®éã®ãããžã§ã¯ãã§ã¯ãŸã èŠã€ãã£ãŠããŸãã PVS-Studioéçã¢ãã©ã€ã¶ãŒã«V3119ã® CïŒèšºæãå®è£ ããåŸãç§ã¯ããã確信ããŸããã 蚺æã«ãŒã«ã¯ãçŸåšã®ã¯ã©ã¹ã§äœ¿çšãããä»®æ³ãŸãã¯ãªãŒããŒã©ã€ããããæé»çãªå®è£ ã€ââãã³ãã®å®£èšãæ¢ããŸãã å®å šã§ãªãç¶æ³ãšã¯ããã®ãããªæ§é ãèŠã€ãããã¯ã©ã¹ã«çžç¶äººãããå¯èœæ§ãããå Žåã§ãã€ãã³ãããªãŒããŒã©ã€ãã§ããŸãïŒ å°å°ãããŠããªãïŒã ã€ãŸãã掟çã¯ã©ã¹ã§ä»®æ³ã€ãã³ããŸãã¯æ¢ã«åå®çŸ©ãããã€ãã³ããåå®çŸ©ããç¶æ³ã仮説çã«å¯èœã«ãªãå Žåã§ãã ãã®æ¹æ³ã§èŠã€ãã£ãèŠåã«ã€ããŠã¯ã次ã®ã»ã¯ã·ã§ã³ã§èª¬æããŸãã
å®éã®ãããžã§ã¯ãã®äŸ
PVS-Studioã¢ãã©ã€ã¶ãŒã®å質ããã¹ãããããã«ããã¹ããããžã§ã¯ãã®ããŒã«ã䜿çšããŸãã ä»®æ³ã«ãŒã«ããã³åå®çŸ©ãããã€ãã³ãã«æ°ããã«ãŒã«V3119ãã¢ãã©ã€ã¶ãŒã«è¿œå ããåŸããããžã§ã¯ãã®ããŒã«å šäœããã§ãã¯ãããŸããã åãåã£ãèŠåã®åæã«ã€ããŠèª¬æããŸãã
ããºãªã³
PVS-Studioã䜿çšããŠãã®ãããžã§ã¯ãããã§ãã¯ããããšãç®çãšããèšäºããããŸããã 次ã«ãä»®æ³ã€ãã³ãããã³ãªãŒããŒã©ã€ããããã€ãã³ãã«é¢é£ããã¢ãã©ã€ã¶ãŒã®èŠåããªã¹ãããŸãã
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ãªãŒããŒã©ã€ããããã€ãã³ããéå§æžã¿ããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãŒãæ瀺çã«å®è£ ãããããsealedãããŒã¯ãŒãã䜿çšããããšãæ€èšããŠãã ããã GlobalOperationNotificationServiceFactory.cs 33
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠå ïŒ V3119ãªãŒããŒã©ã€ããããã€ãã³ããåæ¢ããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãŒãæ瀺çã«å®è£ ãããããsealedãããŒã¯ãŒãã䜿çšããããšãæ€èšããŠãã ããã GlobalOperationNotificationServiceFactory.cs 34
private class NoOpService : AbstractGlobalOperationNotificationService { .... public override event EventHandler Started; public override event EventHandler<GlobalOperationEventArgs> Stopped; .... public NoOpService() { .... var started = Started; //<= var stopped = Stopped; //<= } .... }
ãã®å Žåãä»®æ³ã€ãã³ãã®åŒ·å¶çãªåå®çŸ©ã®ç¶æ³ã«å¯ŸåŠããå¯èœæ§ãæãé«ããªããŸãã åºæ¬ã¯ã©ã¹AbstractGlobalOperationNotificationServiceã¯æœè±¡ã¯ã©ã¹ã§ããã Startedããã³Stoppedæœè±¡ã€ãã³ãã®å®çŸ©ãå«ãŸããŠããŸãã
internal abstract class AbstractGlobalOperationNotificationService : IGlobalOperationNotificationService { public abstract event EventHandler Started; public abstract event EventHandler<GlobalOperationEventArgs> Stopped; .... }
ããªã²ãŒãã¯ã NoOpServiceã¡ãœããã§éå§ããã³åæ¢ãããããŒã«ã«å€æ°ã«åã«å²ãåœãŠããããããªãæ¹æ³ã§ã䜿çšãããªãããããªãŒããŒã©ã€ããããStartedããã³Stoppedã€ãã³ãã®ãããªã䜿çšã¯å®å šã«æ確ã§ã¯ãããŸããã ãã ããã¢ãã©ã€ã¶ãŒãèŠåããããããã®ç¶æ³ã¯æœåšçã«å±éºã§ãã
ã·ã£ãŒãéçº
ãã®ãããžã§ã¯ãã®æ€èšŒã«ã€ããŠã¯ã以åã«èšäºã§èª¬æããŸããã V3119ã¢ãã©ã€ã¶ãŒã®èŠåã®ãªã¹ãã瀺ããŸãã
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠå ïŒ V3119ãªãŒããŒã©ã€ããããã€ãã³ããParseInformationUpdatedããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãŒãæ瀺çã«å®è£ ãããããsealedãããŒã¯ãŒãã䜿çšããããšãæ€èšããŠãã ããã CompilableProject.cs 397
.... public override event EventHandler<ParseInformationEventArgs> ParseInformationUpdated = delegate {}; .... public override void OnParseInformationUpdated (....) { .... SD.MainThread.InvokeAsyncAndForget (delegate { ParseInformationUpdated(null, args); }); //<= } ....
ãªãŒããŒã©ã€ããããä»®æ³ã€ãã³ããæ€åºãããŸããã çŸåšã®ã¯ã©ã¹ããç¶æ¿ãã掟çã¯ã©ã¹ã§ParseInformationUpdatedã€ãã³ããåå®çŸ©ãããšãå±éºãåŸ ã¡åããŸãã
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ãªãŒããŒã©ã€ããããã€ãã³ããShouldApplyExtensionsInvalidatedããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãŒãæ瀺çã«å®è£ ãããããsealedãããŒã¯ãŒãã䜿çšããããšãæ€èšããŠãã ããã DefaultExtension.cs 127
.... public override event EventHandler<DesignItemCollectionEventArgs> ShouldApplyExtensionsInvalidated; .... protected void ReapplyExtensions (ICollection<DesignItem> items) { if (ShouldApplyExtensionsInvalidated != null) { ShouldApplyExtensionsInvalidated(this, //<= new DesignItemCollectionEventArgs(items)); } } ....
ããã§ãããªãŒããŒã©ã€ããããä»®æ³ã€ãã³ãã®äœ¿çšãæ€åºãããŸããã
å®å®ãšã³ãžãã¢
ãŸãããã®ãããžã§ã¯ãã¯ä»¥åã«PVS-Studioã䜿çšããŠãã¹ããããŸããã æ€èšŒçµæã¯èšäºã«èšèŒãããŠããŸã ã æ°ããV3119蚺æã§ã¯ã2ã€ã®èŠåãçæãããŸããã
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ä»®æ³ã€ãã³ããOnAfterComponentAddããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãæ瀺çã«å®è£ ããããšãæ€èšããŠãã ããã MyInventoryAggregate.cs 209
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ä»®æ³ã€ãã³ããOnBeforeComponentRemoveããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãæ瀺çã«å®è£ ããããšãæ€èšããŠãã ããã MyInventoryAggregate.cs 218
.... public virtual event Action<MyInventoryAggregate, MyInventoryBase> OnAfterComponentAdd; public virtual event Action<MyInventoryAggregate, MyInventoryBase> OnBeforeComponentRemove; .... public void AfterComponentAdd(....) { .... if (OnAfterComponentAdd != null) { OnAfterComponentAdd(....); // <= } } .... public void BeforeComponentRemove(....) { .... if (OnBeforeComponentRemove != null) { OnBeforeComponentRemove(....); } } ....
ããã§ã¯ãåå®çŸ©ãããã€ãã³ãã§ã¯ãªããä»®æ³ã€ãã³ãã®å®£èšãšäœ¿çšãæ±ã£ãŠããŸãã äžè¬ã«ãç¶æ³ã¯ä»¥åã«èæ ®ããããã®ãšå€ãããŸããã
Ravendb
RavenDBãããžã§ã¯ãã¯ããããããNoSQLãïŒãŸãã¯ããã¥ã¡ã³ãæåïŒããŒã¿ããŒã¹ã§ãã 詳现ãªèª¬æã¯å ¬åŒãŠã§ããµã€ãã§å ¥æã§ããŸãã ãããžã§ã¯ãã¯.NETã䜿çšããŠéçºããããã®ãœãŒã¹ã³ãŒãã¯GitHubã§å ¥æã§ããŸã ã PVS-Studioã¢ãã©ã€ã¶ãŒã«ããRavenDBã®ãã§ãã¯ã«ãããV3119ã®3ã€ã®èŠåãæããã«ãªããŸããã
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ãªãŒããŒã©ã€ããããã€ãã³ããAfterDisposeããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãŒãæ瀺çã«å®è£ ãããããsealedãããŒã¯ãŒãã䜿çšããããšãæ€èšããŠãã ããã DocumentStore.cs 273
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ãªãŒããŒã©ã€ããããã€ãã³ããAfterDisposeããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãŒãæ瀺çã«å®è£ ãããããsealedãããŒã¯ãŒãã䜿çšããããšãæ€èšããŠãã ããã ShardedDocumentStore.cs 104
ãããã®èŠåã¯äž¡æ¹ãšããåæ§ã®ã³ãŒãã¹ããããã«å¯ŸããŠçºè¡ãããŸãã 次ã®ãã©ã°ã¡ã³ãã®ãããããèããŠãã ãã
public class DocumentStore : DocumentStoreBase { .... public override event EventHandler AfterDispose; .... public override void Dispose() { .... var afterDispose = AfterDispose; //<= if (afterDispose != null) afterDispose(this, EventArgs.Empty); } .... }
DocumentStoreã¯ã©ã¹ã§ãªãŒããŒã©ã€ããããOverDisposeã€ãã³ãã¯ãããŒã¹ã®æœè±¡ã¯ã©ã¹DocumentStoreBaseã§æœè±¡ãšããŠå®£èšãããŸãã
public abstract class DocumentStoreBase : IDocumentStore { .... public abstract event EventHandler AfterDispose; .... }
åã®äŸã®ããã«ã AfterDisposeä»®æ³ã€ãã³ãããªãŒããŒã©ã€ãããã DocumentStoreãã掟çããã¯ã©ã¹ã§äœ¿çšãããå Žåã ã¢ãã©ã€ã¶ãŒã¯æœåšçãªå±éºã«ã€ããŠèŠåããŸãã
PVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒ V3119ä»®æ³ã€ãã³ãããšã©ãŒããåŒã³åºããšãäºæããªãåäœãçºçããå ŽåããããŸãã ã€ãã³ãã¢ã¯ã»ãµãæ瀺çã«å®è£ ããããšãæ€èšããŠãã ããã JsonSerializer.cs 1007
.... public virtual event EventHandler<ErrorEventArgs> Error; .... internal void OnError(....) { EventHandler<ErrorEventArgs> error = Error; //<= if (error != null) error(....); } ....
ããã§ãä»®æ³ã€ãã³ãã®çºè¡šãšäœ¿çšãè¡ãããŸãã ç¹°ãè¿ããŸãããäžç¢ºå®ãªåäœã®ãªã¹ã¯ããããŸãã
ãããã«
ããã§ç 究ãçµäºããæé»çã«å®è£ ãããä»®æ³ã€ãã³ãã䜿çšãã䟡å€ã¯æ¬åœã«ãªããšçµè«ä»ããŸãã CïŒã§ã®å®è£ ã®æ§è³ªã«ããããã®ãããªã€ãã³ãã䜿çšãããšãæªå®çŸ©ã®åäœãçºçããå¯èœæ§ããããŸãã åå®çŸ©ãããä»®æ³ã€ãã³ãã䜿çšããå¿ èŠãããå ŽåïŒããšãã°ãæœè±¡ã¯ã©ã¹ããç¶æ¿ããå ŽåïŒãæ瀺çã«è¿œå ããã³åé€ããã¢ã¯ã»ãµãŒã䜿çšããŠããããæ éã«è¡ãå¿ èŠããããŸãã ã¯ã©ã¹ãŸãã¯ã€ãã³ãã宣èšãããšãã«ã sealedããŒã¯ãŒãã䜿çšããããšãã§ããŸãã ãããŠãã¡ãããéçã³ãŒãåæããŒã«ãããšãã°PVS-Studioã䜿çšããå¿ èŠããããŸãã
ãã®èšäºãè±èªåã®èŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒSergey Khrenovã CïŒã®ä»®æ³ã€ãã³ãïŒäœããããããã£ã ã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§åçãéããŸããïŒ PVS-StudioããŒãžã§ã³2015ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã