在C#中,您能否将一种泛型类型转换为另一种';st参数是第一个';那是什么?
我遇到了一个问题,我试图将一个泛型转换为另一个泛型,其中第二个泛型T参数是第一个中使用的泛型T参数的子类 这是我的代码,为便于理解而简化在C#中,您能否将一种泛型类型转换为另一种';st参数是第一个';那是什么?,c#,generics,casting,C#,Generics,Casting,我遇到了一个问题,我试图将一个泛型转换为另一个泛型,其中第二个泛型T参数是第一个中使用的泛型T参数的子类 这是我的代码,为便于理解而简化 public partial class HierarchicalItem { public ObservableHierarchicalCollection<HierarchicalItem> ContainingCollection{ get; private set; } public HierarchicalItem Pa
public partial class HierarchicalItem
{
public ObservableHierarchicalCollection<HierarchicalItem> ContainingCollection{ get; private set; }
public HierarchicalItem Parent{ get{
return (ContainingCollection != null)
? ContainingCollection.Owner
: null;
}}
}
public partial class HierarchicalItem
{
public class ObservableHierarchicalCollection<T> : ObservableCollection<T>
where T : HierarchicalItem
{
public ObservableHierarchicalCollection(HierarchicalItem owner)
{
this.Owner = owner;
}
public HierarchicalItem Owner{ get; private set; }
private void ExistingMemberCheck(T item)
{
if(item.ContainingCollection != null) throw new ExistingMemberException();
item.ContainingCollection = this; // <-- This fails because of casting
}
protected override void InsertItem(int index, T item)
{
ExistingMemberCheck(item);
base.InsertItem(index, item);
}
protected override void SetItem(int index, T item)
{
CheckParent(item);
// Get the item and unhook the hierarchy
var existingItem = this[index];
existingItem.ContainingCollection = null;
base.SetItem(index, item);
}
protected override void RemoveItem(int index)
{
// Get the item and unhook the hierarchy
var existingItem = this[index];
existingItem.ContainingCollection = null;
base.RemoveItem(index);
}
}
}
公共部分类层次结构项
{
public observehierarchicalcollection包含集合{get;private set;}
公共层次结构项目父项{get{
返回(包含集合!=null)
?包含集合。所有者
:null;
}}
}
公共部分类层次结构项
{
公共类ObservableHierarchicalCollection:ObservableCollection
其中T:HierarchicalItem
{
公共ObservieHierarchicalCollection(HierarchicalItem所有者)
{
这个。所有者=所有者;
}
公共层次结构项目所有者{get;private set;}
私有无效现有成员检查(T项)
{
如果(item.ContainingCollection!=null)抛出新的ExistingMemberException();
item.ContainingCollection=this;//C#4.0支持显式协方差和反向方差
您可以在ObservableCollection接口声明中使用out关键字:
public interface ObservableCollection <out T> {
//The ObservableCollection methods
}
公共接口ObservableCollection{
//可观测采集方法
}
然后,接口将是共变的
更多信息:
将顶部切换为类似以下内容:
public partial class HierarchicalItem
{
public INotifyCollectionChanged ContainingCollection { get; private set; }
public HierarchicalItem Parent
{
get
{
return (ContainingCollection != null)
? ((ObservableHierarchicalCollection<HierarchicalItem>)ContainingCollection).Owner
: null;
}
}
}
公共部分类层次结构项
{
public INotifyCollectionChanged包含集合{get;private set;}
公共层次结构项父项
{
得到
{
返回(包含集合!=null)
((ObservableHierarchicalCollection)包含集合)。所有者
:null;
}
}
}
您必须使用非通用接口,因为正如Nicholas所说,协方差在这种情况下是您的敌人。在您的示例中,ObservateHierarchicalCollection
仅使用T=HierarchicalItem
进行实例化。如果总是这样,您可以尝试将集合设置为非通用和inheri改为从可观察到的采集中提取
如果没有,您可以将HierarchicalItem
更改为抽象和通用,(HierarchicalItem,其中T:HierarchicalItem
)就像IComparable和类似的接口一样。然后你会有DerivedItem:HierarchicalItem
,它会有一个类型为ObserverHierarchicalCollection的包含集合。请注意,这可能会使混合项目类型变得困难。看看@Magnus的可能重复,而不是重复。他说的是成员。我说的是abo但是集合本身。另外,我专门指的是所有可能显示这一点的泛型,仅以我的代码为例。他的重点是列表及其内容。(看,我本可以用非基于集合的类来演示这一点。)你说得对。需要声明为接口。-修复了答案。请注意,我的答案假设为3.5或更低。如果使用4.0,请使用Yochai的答案。