我可以创建List <WeakReference >吗?

我正在尝试使用4.5generics实现创建一个WeakReference列表,以便我可以避免类型检查和WeakReference目标的转换。 但是, WeakReference似乎不支持协方差,所以我试图建立一个解决方法。

我认为它应该是可行的,因为每个T都是特定inheritance链中的一种类型。 那么,我在想的就是这样:

 public class Animal { } public class Tiger : Animal { } public class Wolf : Animal { } var mylist = new List<WeakReference>(); mylist.Add(new WeakReference(new Animal())); mylist.Add(new WeakReference(new Tiger())); mylist.Add(new WeakReference(new Wolf())); 

我已经尝试为WeakReference创建一个包装类(因为它是不可inheritance的),但这不起作用。 无论如何,列表将不接受除WeakReference之外的任何类型的WeakReference

我可以创建自己的通用WeakReference实现,但这似乎是打败了这一点,因为我在其中进行类型转换。 我找不到任何文档,但我有点假设框架版本更好地处理这个问题。

还有另一种方法可以解决这个问题,我没想到,或者我是在咆哮错误的树?

WeakReference是不变的,因为它允许设置值,如果它是协变的则不会有效。 为了使它协变,你需要在引用周围做一个只读包装,并使用一个接口。

 public interface IReadOnlyWeakReference { T Value { get; } } public class WeakReferenceWrapper : IReadOnlyWeakReference where T : class { private WeakReference reference; public WeakReferenceWrapper(WeakReference reference) { this.reference = reference; } public T Value { get { T output; if (reference.TryGetTarget(out output)) return output; else return default(T); } } } 

转换的扩展方法也有些方便:

 public static IReadOnlyWeakReference AsReadOnly( this WeakReference reference) where T : class { return new WeakReferenceWrapper(reference); } 

现在我们可以写:

 var mylist = new List>(); mylist.Add(new WeakReference(new Animal()).AsReadOnly()); mylist.Add(new WeakReference(new Tiger()).AsReadOnly()); mylist.Add(new WeakReference(new Wolf()).AsReadOnly()); 

我的建议是创建一个WeakReferences列表(List)并将其公开为IEnumerable,如下所示:

 private List innerList = new List(); public IEnumerable List { get { return (this.innerList.Where(x => x.Target is T).Select(x => (T) x.Target)); } } 

您可以简单地使用WeakReference本身,反正列表的类型为List> ,因此即使使用协方差,您也无法访问更多派生成员。

 var mylist = new List>(); mylist.Add(new WeakReference(new Animal())); mylist.Add(new WeakReference(new Tiger())); mylist.Add(new WeakReference(new Wolf())); 

或者如果您希望保留更具体的类型,有一种方法。 我之前用访客模式解决了这个问题。 看看是否有帮助 。