[{"data":1,"prerenderedAt":703},["ShallowReactive",2],{"blog:2006:implementingweakreferencet":3,"blogMore-Development":689,"comments-implementingweakreferencet":702},{"id":4,"title":5,"body":6,"category":672,"commentCount":117,"date":673,"description":674,"excerpt":675,"extension":676,"filenames":677,"hidden":678,"image":677,"meta":679,"minutes":110,"navigation":113,"path":680,"seo":681,"showCategory":677,"stem":682,"tags":683,"updated":677,"url":686,"wordCount":687,"__hash__":688},"content\u002Fblog\u002F2006\u002Fimplementingweakreferencet.md","Implementing a generic WeakReference\u003CT> in C#",{"type":7,"value":8,"toc":670},"minimark",[9,25,41,50,57,63,647,660,666],[10,11,12],"blockquote",{},[13,14,15,16],"p",{},"Check out the replacement ",[17,18,20,24],"a",{"href":19},"\u002Fblog\u002F2006\u002Fequatable_weak_references\u002F",[21,22,23],"code",{},"EquatableWeakReference\u003CT>"," class",[13,26,27,28,34,35,40],{},"A ",[17,29,33],{"href":30,"rel":31},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWeak_reference",[32],"nofollow","weak reference"," lets you hold a reference to an object that will not prevent it from being garbage collected. There are a few scenarios where this might be important, such as listening for events, caching, various ",[17,36,39],{"href":37,"rel":38},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FModel-view-controller",[32],"MVC patterns",".",[13,42,43,44,49],{},".NET and Java supports weak references with the aptly named ",[17,45,48],{"href":46,"rel":47},"https:\u002F\u002Fwindowssdk.msdn.microsoft.com\u002Fen-us\u002Flibrary\u002Fsystem.weakreference.aspx",[32],"WeakReference"," class. In .NET it exposes a .Target property of type object that weakly points to whatever you like.",[13,51,52,53,56],{},"Java also sports a generic ",[21,54,55],{},"WeakReference\u003CT>"," to give you a strongly typed version so it’s somewhat puzzling why .NET doesn’t.",[13,58,59,60,62],{},"Here is my attempt at a ",[21,61,55],{}," for .NET. It works fine in the scenarios I’ve used and performance is close to the non-generic version but a quick glance at the SSCLI code for WeakReference reveals that the standard version is a little more complicated and it’s possible there is a reason for that, most likely due to finalizer issues.",[64,65,70],"pre",{"className":66,"code":67,"language":68,"meta":69,"style":69},"language-csharp shiki shiki-themes everforest-light dracula","using System;\nusing System.Runtime.InteropServices;\n\npublic class WeakReference\u003CT> : IDisposable {\n  private GCHandle handle;\n  private bool trackResurrection;\n\n  public WeakReference(T target)\n    : this(target, false) {\n  }\n\n  public WeakReference(T target, bool trackResurrection) {\n    this.trackResurrection = trackResurrection;\n    this.Target = target;\n  }\n\n  ~WeakReference() {\n    Dispose();\n  }\n\n  public void Dispose() {\n    handle.Free();\n    GC.SuppressFinalize(this);\n  }\n\n  public virtual bool IsAlive {\n    get { return (handle.Target != null); }\n  }\n\n  public virtual bool TrackResurrection {\n    get { return this.trackResurrection; }\n  }\n\n  public virtual T Target {\n    get {\n      object o = handle.Target;\n      if ((o == null) || (!(o is T)))\n        return default(T);\n      else\n        return (T)o;\n    }\n    set {\n      handle = GCHandle.Alloc(value,\n        this.trackResurrection ? GCHandleType.WeakTrackResurrection : GCHandleType.Weak);\n    }\n  }\n}\n","csharp","",[21,71,72,89,108,115,145,157,169,174,195,215,221,226,250,267,282,287,292,303,312,317,322,335,346,362,367,372,385,411,416,421,433,452,457,462,475,482,501,538,553,559,571,577,585,602,631,636,641],{"__ignoreMap":69},[73,74,77,81,85],"span",{"class":75,"line":76},"line",1,[73,78,80],{"class":79},"smiwp","using",[73,82,84],{"class":83},"sjYfO"," System",[73,86,88],{"class":87},"s6Vpi",";\n",[73,90,92,94,96,98,101,103,106],{"class":75,"line":91},2,[73,93,80],{"class":79},[73,95,84],{"class":83},[73,97,40],{"class":87},[73,99,100],{"class":83},"Runtime",[73,102,40],{"class":87},[73,104,105],{"class":83},"InteropServices",[73,107,88],{"class":87},[73,109,111],{"class":75,"line":110},3,[73,112,114],{"emptyLinePlaceholder":113},true,"\n",[73,116,118,122,124,128,131,135,138,142],{"class":75,"line":117},4,[73,119,121],{"class":120},"s9HRq","public",[73,123,24],{"class":79},[73,125,127],{"class":126},"sPLAf"," WeakReference",[73,129,130],{"class":87},"\u003C",[73,132,134],{"class":133},"sAO9U","T",[73,136,137],{"class":87},"> : ",[73,139,141],{"class":140},"snuxY","IDisposable",[73,143,144],{"class":87}," {\n",[73,146,148,151,154],{"class":75,"line":147},5,[73,149,150],{"class":120},"  private",[73,152,153],{"class":140}," GCHandle",[73,155,156],{"class":87}," handle;\n",[73,158,160,162,166],{"class":75,"line":159},6,[73,161,150],{"class":120},[73,163,165],{"class":164},"sXAHl"," bool",[73,167,168],{"class":87}," trackResurrection;\n",[73,170,172],{"class":75,"line":171},7,[73,173,114],{"emptyLinePlaceholder":113},[73,175,177,180,183,186,188,192],{"class":75,"line":176},8,[73,178,179],{"class":120},"  public",[73,181,127],{"class":182},"sS4Kt",[73,184,185],{"class":87},"(",[73,187,134],{"class":140},[73,189,191],{"class":190},"s7cAX"," target",[73,193,194],{"class":87},")\n",[73,196,198,201,205,208,212],{"class":75,"line":197},9,[73,199,200],{"class":87},"    : ",[73,202,204],{"class":203},"sKO3f","this",[73,206,207],{"class":87},"(target, ",[73,209,211],{"class":210},"s3Ipq","false",[73,213,214],{"class":87},") {\n",[73,216,218],{"class":75,"line":217},10,[73,219,220],{"class":87},"  }\n",[73,222,224],{"class":75,"line":223},11,[73,225,114],{"emptyLinePlaceholder":113},[73,227,229,231,233,235,237,239,242,245,248],{"class":75,"line":228},12,[73,230,179],{"class":120},[73,232,127],{"class":182},[73,234,185],{"class":87},[73,236,134],{"class":140},[73,238,191],{"class":190},[73,240,241],{"class":87},", ",[73,243,244],{"class":164},"bool",[73,246,247],{"class":190}," trackResurrection",[73,249,214],{"class":87},[73,251,253,256,258,262,265],{"class":75,"line":252},13,[73,254,255],{"class":203},"    this",[73,257,40],{"class":87},[73,259,261],{"class":260},"sSKRk","trackResurrection",[73,263,264],{"class":120}," =",[73,266,168],{"class":87},[73,268,270,272,274,277,279],{"class":75,"line":269},14,[73,271,255],{"class":203},[73,273,40],{"class":87},[73,275,276],{"class":260},"Target",[73,278,264],{"class":120},[73,280,281],{"class":87}," target;\n",[73,283,285],{"class":75,"line":284},15,[73,286,220],{"class":87},[73,288,290],{"class":75,"line":289},16,[73,291,114],{"emptyLinePlaceholder":113},[73,293,295,298,300],{"class":75,"line":294},17,[73,296,297],{"class":87},"  ~",[73,299,48],{"class":182},[73,301,302],{"class":87},"() {\n",[73,304,306,309],{"class":75,"line":305},18,[73,307,308],{"class":182},"    Dispose",[73,310,311],{"class":87},"();\n",[73,313,315],{"class":75,"line":314},19,[73,316,220],{"class":87},[73,318,320],{"class":75,"line":319},20,[73,321,114],{"emptyLinePlaceholder":113},[73,323,325,327,330,333],{"class":75,"line":324},21,[73,326,179],{"class":120},[73,328,329],{"class":164}," void",[73,331,332],{"class":182}," Dispose",[73,334,302],{"class":87},[73,336,338,341,344],{"class":75,"line":337},22,[73,339,340],{"class":87},"    handle.",[73,342,343],{"class":182},"Free",[73,345,311],{"class":87},[73,347,349,352,355,357,359],{"class":75,"line":348},23,[73,350,351],{"class":87},"    GC.",[73,353,354],{"class":182},"SuppressFinalize",[73,356,185],{"class":87},[73,358,204],{"class":203},[73,360,361],{"class":87},");\n",[73,363,365],{"class":75,"line":364},24,[73,366,220],{"class":87},[73,368,370],{"class":75,"line":369},25,[73,371,114],{"emptyLinePlaceholder":113},[73,373,375,377,380,382],{"class":75,"line":374},26,[73,376,179],{"class":120},[73,378,379],{"class":120}," virtual",[73,381,165],{"class":164},[73,383,384],{"class":87}," IsAlive {\n",[73,386,388,391,394,397,400,402,405,408],{"class":75,"line":387},27,[73,389,390],{"class":164},"    get",[73,392,393],{"class":87}," { ",[73,395,396],{"class":79},"return",[73,398,399],{"class":87}," (handle.",[73,401,276],{"class":260},[73,403,404],{"class":120}," !=",[73,406,407],{"class":210}," null",[73,409,410],{"class":87},"); }\n",[73,412,414],{"class":75,"line":413},28,[73,415,220],{"class":87},[73,417,419],{"class":75,"line":418},29,[73,420,114],{"emptyLinePlaceholder":113},[73,422,424,426,428,430],{"class":75,"line":423},30,[73,425,179],{"class":120},[73,427,379],{"class":120},[73,429,165],{"class":164},[73,431,432],{"class":87}," TrackResurrection {\n",[73,434,436,438,440,442,445,447,449],{"class":75,"line":435},31,[73,437,390],{"class":164},[73,439,393],{"class":87},[73,441,396],{"class":79},[73,443,444],{"class":203}," this",[73,446,40],{"class":87},[73,448,261],{"class":260},[73,450,451],{"class":87},"; }\n",[73,453,455],{"class":75,"line":454},32,[73,456,220],{"class":87},[73,458,460],{"class":75,"line":459},33,[73,461,114],{"emptyLinePlaceholder":113},[73,463,465,467,469,472],{"class":75,"line":464},34,[73,466,179],{"class":120},[73,468,379],{"class":120},[73,470,471],{"class":140}," T",[73,473,474],{"class":87}," Target {\n",[73,476,478,480],{"class":75,"line":477},35,[73,479,390],{"class":164},[73,481,144],{"class":87},[73,483,485,488,491,494,497,499],{"class":75,"line":484},36,[73,486,487],{"class":164},"      object",[73,489,490],{"class":87}," o ",[73,492,493],{"class":120},"=",[73,495,496],{"class":87}," handle.",[73,498,276],{"class":260},[73,500,88],{"class":87},[73,502,504,507,510,513,515,518,521,524,527,530,533,535],{"class":75,"line":503},37,[73,505,506],{"class":79},"      if",[73,508,509],{"class":87}," ((o ",[73,511,512],{"class":120},"==",[73,514,407],{"class":210},[73,516,517],{"class":87},") ",[73,519,520],{"class":120},"||",[73,522,523],{"class":87}," (",[73,525,526],{"class":120},"!",[73,528,529],{"class":87},"(o ",[73,531,532],{"class":79},"is",[73,534,471],{"class":140},[73,536,537],{"class":87},")))\n",[73,539,541,544,547,549,551],{"class":75,"line":540},38,[73,542,543],{"class":79},"        return",[73,545,546],{"class":79}," default",[73,548,185],{"class":87},[73,550,134],{"class":140},[73,552,361],{"class":87},[73,554,556],{"class":75,"line":555},39,[73,557,558],{"class":79},"      else\n",[73,560,562,564,566,568],{"class":75,"line":561},40,[73,563,543],{"class":79},[73,565,523],{"class":87},[73,567,134],{"class":140},[73,569,570],{"class":87},")o;\n",[73,572,574],{"class":75,"line":573},41,[73,575,576],{"class":87},"    }\n",[73,578,580,583],{"class":75,"line":579},42,[73,581,582],{"class":164},"    set",[73,584,144],{"class":87},[73,586,588,591,593,596,599],{"class":75,"line":587},43,[73,589,590],{"class":87},"      handle ",[73,592,493],{"class":120},[73,594,595],{"class":87}," GCHandle.",[73,597,598],{"class":182},"Alloc",[73,600,601],{"class":87},"(value,\n",[73,603,605,608,610,612,615,618,621,624,626,629],{"class":75,"line":604},44,[73,606,607],{"class":203},"        this",[73,609,40],{"class":87},[73,611,261],{"class":260},[73,613,614],{"class":120}," ?",[73,616,617],{"class":87}," GCHandleType.",[73,619,620],{"class":260},"WeakTrackResurrection",[73,622,623],{"class":120}," :",[73,625,617],{"class":87},[73,627,628],{"class":260},"Weak",[73,630,361],{"class":87},[73,632,634],{"class":75,"line":633},45,[73,635,576],{"class":87},[73,637,639],{"class":75,"line":638},46,[73,640,220],{"class":87},[73,642,644],{"class":75,"line":643},47,[73,645,646],{"class":87},"}\n",[10,648,649],{},[13,650,651,652,654,655,657,658,40],{},"I’ve allowed ",[21,653,276],{}," to be settable against my better judgment to bring it more in like with ",[21,656,48],{},". It’s still not serializable though unlike ",[21,659,48],{},[13,661,662],{},[663,664,665],"em",{},"[)amien",[667,668,669],"style",{},"html pre.shiki code .smiwp, html code.shiki .smiwp{--shiki-default:#F85552;--shiki-dark:#FF79C6}html pre.shiki code .sjYfO, html code.shiki .sjYfO{--shiki-default:#DF69BA;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .s6Vpi, html code.shiki .s6Vpi{--shiki-default:#5C6A72;--shiki-dark:#F8F8F2}html pre.shiki code .s9HRq, html code.shiki .s9HRq{--shiki-default:#F57D26;--shiki-dark:#FF79C6}html pre.shiki code .sPLAf, html code.shiki .sPLAf{--shiki-default:#3A94C5;--shiki-dark:#8BE9FD}html pre.shiki code .sAO9U, html code.shiki .sAO9U{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .snuxY, html code.shiki .snuxY{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .sXAHl, html code.shiki .sXAHl{--shiki-default:#3A94C5;--shiki-dark:#FF79C6}html pre.shiki code .sS4Kt, html code.shiki .sS4Kt{--shiki-default:#8DA101;--shiki-dark:#50FA7B}html pre.shiki code .s7cAX, html code.shiki .s7cAX{--shiki-default:#5C6A72;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .sKO3f, html code.shiki .sKO3f{--shiki-default:#DF69BA;--shiki-default-font-style:inherit;--shiki-dark:#BD93F9;--shiki-dark-font-style:italic}html pre.shiki code .s3Ipq, html code.shiki .s3Ipq{--shiki-default:#DF69BA;--shiki-dark:#BD93F9}html pre.shiki code .sSKRk, html code.shiki .sSKRk{--shiki-default:#35A77C;--shiki-dark:#F8F8F2}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":69,"searchDepth":91,"depth":91,"links":671},[],"Development","2006-08-01T16:51:32+00:00","A weak reference lets you hold a reference to an object that will not prevent it from being garbage collected. There are a few scenarios where this might be important, such as listening for events, caching, various MVC patterns.","[object Object]","md",null,false,{},"\u002Fblog\u002F2006\u002Fimplementingweakreferencet",{"title":5,"description":674},"blog\u002F2006\u002Fimplementingweakreferencet",[684,685],".NET","C#","\u002Fblog\u002F2006\u002Fimplementingweakreferencet\u002F",461,"T5qSat3Oe8o0ZFEYu15nexdWKiAYBk27qJYUEsWgJRw",[690,694,698],{"title":691,"date":692,"url":693},"Transactions in the MongoDB EF Core Provider","2025-10-25","\u002Fblog\u002F2025\u002Fmongodb-explicit-transactions\u002F",{"title":695,"date":696,"url":697},"Queryable Encryption with the MongoDB EF Core Provider","2025-09-22","\u002Fblog\u002F2025\u002Fmongodb-queryable-encryption\u002F",{"title":699,"date":700,"url":701},"Lazy Loading with EF Core Proxies","2025-04-02","\u002Fblog\u002F2025\u002Fef-proxies\u002F",[],1780900533129]