我想创建一个可排序的 observableCollection 所以我开始创建一个继承 observable 的类,并使用一些方法对其进行排序,然后我希望该类将索引持久保存到子项中,所以我创建了一个接口(interface),该接口(interface)公开了一个我可以写入的索引属性,并且我限制了 T我的集合类是我的接口(interface),然后我希望能够从每个项目访问 parentCollection 并且这里开始出现问题,因为父集合的类型是通用的...... 我已经尝试了很多解决方案,我认为协方差或不变性是方法,但我无法让它工作......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ClassLibrary1
{
public class SortableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T>, ISortableCollection<T> where T : ISortable<T>
{
public void Sort()
{
//We all know how to sort something
throw new NotImplementedException();
}
protected override void InsertItem(int index, T item)
{
item.Index = index;
item.ParentCollection = this;
base.InsertItem(index, item);
}
}
public interface ISortableCollection<T> : IList<T>
{
void Sort();
}
public interface ISortable<T>
{
Int32 Index { get; set; }
ISortableCollection<T> ParentCollection { get; set; }
}
public class BaseClass : ISortable<BaseClass>
{
public int Index { get; set; }
public ISortableCollection<BaseClass> ParentCollection { get; set; }
}
public class DerivedClass : BaseClass { }
public class Controller
{
SortableCollection<BaseClass> MyBaseSortableList = new SortableCollection<BaseClass>();
SortableCollection<DerivedClass> MyDerivedSortableList = new SortableCollection<DerivedClass>();
public Controller()
{
//do things
}
}
}
这或多或少是设置。
我希望能够创建一个 SortableCollection<DerivedClass>
但是类型不匹配...这是正确的方法吗?
准确的错误是
Error 1 The type 'ClassLibrary1.DerivedClass' cannot be used as type parameter 'T' in the generic type or method
'ClassLibrary1.SortableCollection<T>'
. There is no implicit reference conversion from 'ClassLibrary1.DerivedClass' to'ClassLibrary1.ISortable<ClassLibrary1.DerivedClass>'
. c:\users\luigi.trabacchin\documents\visual studio 2013\Projects\ClassLibrary1\ClassLibrary1\Class1.cs 48 89 ClassLibrary1
最佳答案
问题是你对 T
的约束是“T
必须是 I<T>
”,并且您已通过 DerivedClass
对于 T
,但是DerivedClass
不可转换为 I<DerivedClass>
, 它可转换为 I<BaseClass>
.
我不知道你想用 T
的约束来表示什么成为I<T>
.我知道人们经常使用这种模式来尝试表示 C# 类型系统实际上没有实现的约束。有关详细信息,请参阅我关于该主题的文章:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
我鼓励你大大简化事情;您似乎试图在类型系统中捕获太多信息。
为什么I<D>
的原因不可转换为 I<B>
是因为为了使变体起作用,必须将接口(interface)标记为支持变体;标记 T
与 out
或 in
取决于您是想要协变还是逆变。
但是,由于 IList<T>
是不变的,使派生接口(interface)协变或逆变都是不合法的。考虑 IEnumerable<T>
相反,因为它在 T
中是协变的.
为了使接口(interface)在 T
中是协变的它只需要使用 T
在输出位置。 List<T>
使用 T
在输入和输出位置,所以它不能协变或逆变。
关于c# - 通用接口(interface)中的协变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29447867/