c# – 我可以创建一个List>吗?

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

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

public class Animal { }
public class Tiger : Animal { }
public class Wolf : Animal { }

var mylist = new List<WeakReference<Animal>>();

mylist.Add(new WeakReference<Animal>(new Animal()));
mylist.Add(new WeakReference<Tiger>(new Tiger()));
mylist.Add(new WeakReference<Wolf>(new Wolf()));

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

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

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

解决方法

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

public interface IReadOnlyWeakReference<out T>
{
    T Value { get; }
}

public class WeakReferenceWrapper<T> : IReadOnlyWeakReference<T>
    where T : class
{
    private WeakReference<T> reference;
    public WeakReferenceWrapper(WeakReference<T> reference)
    {
        this.reference = reference;
    }

    public T Value
    {
        get
        {
            T output;
            if (reference.TryGetTarget(out output))
                return output;
            else
                return default(T);
        }
    }
}

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

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

现在我们可以写:

var mylist = new List<IReadOnlyWeakReference<Animal>>();

mylist.Add(new WeakReference<Animal>(new Animal()).AsReadOnly());
mylist.Add(new WeakReference<Tiger>(new Tiger()).AsReadOnly());
mylist.Add(new WeakReference<Wolf>(new Wolf()).AsReadOnly());

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...