Вот еще одно решение, основанное на ответе Meleak , но не требующее обработчика события AutoGeneratingColumn
в коде за каждым связанным DataGrid
:
public static DataView GetBindable2DArray(T[,] array)
{
var table = new DataTable();
for (var i = 0; i < array.GetLength(1); i++)
{
table.Columns.Add(i+1, typeof(bool))
.ExtendedProperties.Add("idx", i); // Save original column index
}
for (var i = 0; i < array.GetLength(0); i++)
{
table.Rows.Add(table.NewRow());
}
var view = new DataView(table);
for (var ri = 0; ri < array.GetLength(0); ri++)
{
for (var ci = 0; ci < array.GetLength(1); ci++)
{
view[ri][ci] = array[ri, ci];
}
}
// Avoids writing an 'AutogeneratingColumn' handler
table.ColumnChanged += (s, e) =>
{
var ci = (int)e.Column.ExtendedProperties["idx"]; // Retrieve original column index
var ri = e.Row.Table.Rows.IndexOf(e.Row); // Retrieve row index
array[ri, ci] = (T)view[ri][ci];
};
return view;
}
Да, название может показаться немного длиннее. Но не так много, как можно было представить ...
Потому что класс enum уже дает некоторый контекст ( «Какому набору констант он принадлежит?» ), имя экземпляра обычно короче, чем имя константы (строгая типизация уже отличается от аналогичных именованных экземпляров в других перечислениях).
Кроме того, вы можете использовать статический импорт для дальнейшего уменьшения длины. Вы не должны использовать его везде, чтобы избежать недоразумений, но я чувствую, что код, который прочно связан с перечислением, может быть хорошо с этим.
В переключает в перечислении, вы этого не делаете. используйте имя класса. (Переключение невозможно даже в Strings до Java 7.)
В самом классе enum вы используете короткие имена.
Поскольку у перечислений есть методы, многие низкоуровневые коды, которые будут интенсивно использовать константы, могут мигрировать из бизнес-кода в сам класс перечисления (динамический или статический метод). Как мы видели, перенос кода в перечисление еще больше сокращает использование длинных имен.
Константы часто обрабатываются в группах, например if
, которые проверяют равенство с одним из шесть констант или четыре других и т. д. Перечисления снабжены EnumSets
с методом contains
(или аналогично динамическим методом, возвращающим соответствующую группу), что позволяет обрабатывать группа как группа (в качестве дополнительного преимущества обратите внимание, что эти две реализации группировки чрезвычайно быстры - O (1) - и имеют мало памяти!).
С учетом всех этих моментов,
Что касается вопроса о константах, перечисления должны представлять константы одного типа. Если вы используете произвольные константы, это неправильный путь по причинам, описанным в этом другом вопросе.
Если вам нужны только строковые константы, то в отношении подробного кода вы правы. Однако вы можете переопределить метод toString (), возвращающий имя свойства. Если все, что вы хотите сделать, - это объединить строку с другими строками, это избавит вас от лишней многословности в вашем коде.
Однако рассматривали ли вы возможность использования файлов свойств или других средств интернационализации? Часто при определении детализации строк это делается для сообщений пользовательского интерфейса, и их извлечение в отдельный файл может сэкономить вам много работы в будущем и значительно упростить перевод.