Я переименовал вопрос с: «Почему мой UpCast() не компилируется как метод экземпляра, а делает это как расширение?« что-то более полезное для будущего изможденного искателя приключений ».Невозможно преобразовать тип 'T' в 'T'?
Первоначально я планировал внедрить метод UpCast() в качестве метода экземпляра, но в итоге оказался в затруднительном положении над сообщением компилятора, которое, похоже, не имеет смысла. Исходный вопрос ниже, с обновлением.
У меня есть класс контейнера, полученный из ObservableCollection. Только сейчас я пытался написать вентиляционный <> общий метод так, что вместо написания:
Columns = new MegaList<DbTableColumn>();
Columns.AddRange(oracleDictionary.ListTableColumns(tableName)); // IEnumerable<OracleColumn>
// or
(v.Columns = new MegaList<DbTableColumn>()).AddRange(oracleDictionary.ListTableColumns(tableName));
// I could instead write
Columns = oracleDictionary.ListTableColumns(tableName).UpCast<DbTableColumn>();
MegaList является ObservableCollection с некоторыми добавлениями удобных методов, которые я не буду показывать здесь. Поскольку ObservableCollection не имеет ConvertAll(), я пробовал это.
В принципе, почему метод следующего экземпляра не компилируется, но я могу реализовать, казалось бы, эквивалент как метод расширения (указанный внизу), это так?
public class MegaList<T> : ObservableCollection<T>
{
// ...rest of class snipped...
public ObservableCollection<TBase> UpCast<TBase, T>()
where TBase: class
where T : TBase
{
var listUpcast = new ObservableCollection<TBase>();
foreach (T t in this.Items) <-- Error 14 Cannot convert type 'T' to 'T' ??? Excuse me?
listUpcast.Add(t);
return listUpcast;
}
}
Я думаю, что следующее эквивалентно. Просто обменивается «этим» параметром для свойства OberservableCollection.Items, оба сохраняют тип T. Меня особенно путают из-за ограничения типа, которое указывает, что «T должно быть TBase».
static public ObservableCollection<TBase> UpCast<TBase, T>(this ObservableCollection<T> list)
where TBase : class
where T : TBase
{
var listUpcast = new ObservableCollection<TBase>();
foreach (var t in list)
listUpcast.Add(t);
return listUpcast;
}
UPDATE: Ответ ниже, и я нашел следующее, чтобы быть правдой:
- C# имеет общий параметр типа затенения, так же как обычный поле/параметра затенения.
- Я не могу написать ограничение типа в общем методе с использованием параметра типа из охватывающего класса из-за (1), и я не думаю, что существует способ ссылаться на тип в типе ограничения, где T - типичный параметр типа.
Можете ли вы опубликовать определение свойства Items. Тип свойства Items не может быть выведен из использования. –
Это стандартное свойство Items в коллекции базового класса. http://msdn.microsoft.com/en-us/library/ms132435(v=vs.110).aspx –
codenheim