Cosmos/Users/Orvid/Orvid.Concurrent/WeakValueRef.cs

78 lines
2.2 KiB
C#

/*
Copyright 2008 The 'A Concurrent Hashtable' development team
(http://www.codeplex.com/CH/People/ProjectPeople.aspx)
This library is licensed under the GNU Library General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.codeplex.com/CH/license.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Orvid.Concurrent.Collections
{
internal interface IWeakValueRef<V>
{
object Reference{ get; }
bool IsGarbage { get; }
bool GetValue(out V value);
}
internal struct WeakValueRef<V> : IWeakValueRef<V>, IEquatable<WeakValueRef<V>>
where V : class
{
public static WeakValueRef<V> Create(V value)
{ return new WeakValueRef<V> { _valueReference = new WeakReference(value == null ? NullValue : value) }; }
static object NullValue = new object();
WeakReference _valueReference;
public object Reference { get{ return _valueReference; } }
public bool IsGarbage
{ get { return _valueReference.Target == null; } }
public bool GetValue(out V value)
{
object vObj = _valueReference.Target;
if (null == vObj)
{
value = default(V);
return false;
}
value = (V)(object.ReferenceEquals(NullValue, vObj) ? null : vObj);
return true;
}
#region IEquatable<WeakValueRef<V>> Members
public bool Equals(WeakValueRef<V> other)
{
//assume weak
if (object.ReferenceEquals(_valueReference, other._valueReference))
return true;
var thisObj = _valueReference.Target;
var otherObj = other._valueReference.Target;
if (thisObj == null || otherObj == null)
return false;
return EqualityComparer<V>.Default.Equals((V)thisObj, (V)otherObj);
}
public override bool Equals(object obj)
{
return obj is WeakValueRef<V> && this.Equals((WeakValueRef<V>)obj);
}
//no relyable hashcode.
#endregion
}
}