我在一个大型WPF应用程序中准备了一个问题的示例应用程序。
我遇到的问题是将第二种类型的TreeColumn实例obsTreeColumn
向上转换为Collection
。
正如你所看到的,当我只用一种类型时,upcast工作得很好。
方法DoSomethingWithColumn
需要能够使用任何类型的集合作为参数collection
的第二种泛型类型。
public class TreeColumn<T, TValue> where TValue : Collection<T> {
// A lot happens in here...
}
public class Data {
public int Id { get; set; }
public int Code { get; set; }
// And much more...
}
class Program {
static void Main(string[] args) {
var expander = new TreeExpander<Data>();
var obsTreeColumn = new TreeColumn<Data, ObservableCollection<Data>>();
var colTreeColumn = new TreeColumn<Data, Collection<Data>>();
var obsCollection = new ObservableCollection<Data>();
var colCollection = new Collection<Data>();
expander.DoSomethingWithColumn(obsTreeColumn);
expander.DoSomethingWithColumn(colTreeColumn);
expander.DoSomethingWithCollection(obsCollection);
expander.DoSomethingWithCollection(colCollection);
Console.ReadKey();
}
}
class TreeExpander<T> where T : class {
private int _rowCounter;
public void DoSomethingWithColumn(object column) {
// WHY ISN'T THIS CAST WORKING WITH A TreeColumn<T, ObservableCollection<T>>????
var cast2 = column as TreeColumn<T, Collection<T>>;
WriteLine("Cast to 'TreeColumn<T, Collection<T>>': ");
WasCastSuccess(cast2);
WriteLine("");
}
public void DoSomethingWithCollection(object collection) {
var cast2 = collection as Collection<T>;
WriteLine("Cast to 'Collection<T>': ");
WasCastSuccess(cast2);
WriteLine("");
}
private void WasCastSuccess(object o) {
WriteLine(o != null ? "PERFECT!" : "Cast didn't work :(");
}
private void WriteLine(string msg) {
_rowCounter++;
Console.WriteLine(_rowCounter.ToString("00")+": "+msg);
}
}
控制台输出是:
01: Cast to 'TreeColumn<T, Collection<T>>':
02: Cast didn't work :(
03:
04: Cast to 'TreeColumn<T, Collection<T>>':
05: PERFECT!
06:
07: Cast to 'Collection<T>':
08: PERFECT!
09:
10: Cast to 'Collection<T>':
11: PERFECT!
12:
我需要提出一些内容,以便输出的第2行读取PERFECT!
答案 0 :(得分:3)
使用out关键字指定type参数是协变的。
public interface ITreeColumn<T, out TValue> where TValue : Collection<T>
{
// A lot declared in here..
}
public class TreeColumn<T, TValue> : ITreeColumn<T, TValue> where TValue : Collection<T>
{
// A lot happens in here..
}