#c# #generics
#c# #дженерики
Вопрос:
Я задавал этот вопрос раньше, но он был отложен, потому что проблема была «простой» проблемой преобразования. Для меня это не так. Я впервые пытаюсь работать с дженериками.
У меня есть Class
похожий код здесь без каких-либо ошибок:
internal class GridBox<T> : BoxBase // where T : new()
{
public GridBox(Grid grid, GridBoxView view, MessageBoxIcon icon, string caption, ObservableCollection<T> dataSource, MessageBoxButton button)
: base(grid, icon, caption, button)
{
View = view;
DataSource = dataSource;
}
public GridBoxView View { get; set; }
public ObservableCollection<T> DataSource { get; set; }
}
Затем я использую это Class
для передачи большого количества данных между разными Classes
, начиная с кода ниже:
public static T Show<T>(DependencyObject sender, MessageBoxIcon icon, string caption, ObservableCollection<T> dataSource, MessageBoxButton button) where T : IComparable<T>, new()
{
Window window = Window.GetWindow(sender);
Grid grid = Extensions.FindChild<Grid>(window);
GridBoxView gridBox = new GridBoxView();
return gridBox.Show<T>(new GridBox<T>(grid, gridBox, icon, caption, dataSource, button));
}
Этот код может быть скомпилирован без каких-либо ошибок. Прав ли я, если скажу, что where T : IComparable<T>
это необходимо для использования T
внутри Method
, а , new()
для его использования требуется дополнительное new GridBox<T>
? Опять же, впервые экспериментирую с дженериками.
Приведенный выше код, который вызывает Show<T>
, приведен ниже:
internal class GridBoxViewModel<T> : BoxBaseViewModel // where T : new()
{
public T Show<T>(GridBox<T> gridBox)
{
// Set content item
DataSource = gridBox.DataSource;
// Set visual items and block the excecution code
AddView(gridBox.Grid, gridBox.View, gridBox.Icon, gridBox.Caption, gridBox.Button);
// Return value
return SelectedItem;
}
public ObservableCollection<T> DataSource { get; set; }
public T SelectedItem { get; set; }
}
Здесь начинаются проблемы. DataSource = gridBox.DataSource
выдает ошибку, которую он не может преобразовать System.Collections.ObjectModel.ObservableCollection<T>
System.Collections.ObjectModel.ObservableCollection<T>
, которая представляется мне такой же. Оба ссылаются на одно и то же Class Library
[C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5System.dll]
.
Вторая проблема связана с return SelectedItem;
. Ошибка здесь практически такая же, но немного отличается. Он не может быть преобразован 'T'
в 'T [ControlsViewModelsGridBoxViewModel.cs(6)]'
.
Очевидная причина для меня в том, что T
at internal class GridBoxViewModel<T> : BoxBaseViewModel
не совпадает T
с at public T Show<T>(GridBox<T> gridBox)
. Действительно ли это причина, и если да, то как мне справиться с этой проблемой и исправить ее?
Комментарии:
1. Как вы ожидаете, что компилятор сделает вывод, что
T
fromGridBoxViewModel
иT
fromGridBox
имеют один и тот же тип или имеют неявное преобразование между ними?2.
where T: new()
означает, что только типы с конструкторами без параметров являются допустимыми аргументами типа (что позволяет вызыватьnew T();
в классе / методе), иwhere T: IComparable<T>
означаетIComparable<T>
, что в качестве аргументов типа могут использоваться только типы, реализующие интерфейс (что позволяет вызыватьCompareTo
T в классе / методе). Похоже, вы не используете ни один из них в показанном вами коде, поэтому я не уверен, что они вам нужны.
Ответ №1:
Удалите общий параметр из Show
:
public T Show(GridBox<T> gridBox)
параметр T
типа отличается от параметра, объявленного в классе, поэтому вы получаете ошибку компилятора.
Комментарии:
1. Хех, я думаю, довольно очевидно. Это фактически исправило это, tnx. Теперь я могу начать тестирование своего кода, если он действительно работает.