Агрегаты будут неизменными, что не приведет к потере данных для доступа по ссылке. Обнаружение компилятором таких модификаций подполей может привести к полному неявному переназначению.
(Помните, что это вики сообщества, улучшения приветствуются и приветствуются)
aggregate Size
{
int Width;
int Height;
}
aggregate Vector
{
// Default values for constructor.
double X = 0, Y = 0, Z = 0;
}
aggregate Color
{
byte R, G, B, A = 255;
}
aggregate Bar
{
int X;
Qux Qux;
}
aggregate Qux
{
int X, Y;
}
static class Foo
{
// Constant is possible.
const Size Big = new Size(200, 100);
// Inline constructor.
const Vector Gravity = { 0, -9.8, 0 };
// Default value / labeled parameter.
const Color Fuschia = { 255, 0, 255 };
const Vector Up = { y: 1 };
// Sub-aggregate initialization
const Bar Test = { 20, { 4, 3 } };
static void SetVelocity(Vector velocity = { 0, 1, 0 }) { ... }
static void SetGravity(Vector gravity = Foo.Gravity) { ... }
static void Main()
{
Vector v = { 1, 2, 3 };
double y = v.Y; // Valid.
v.Y = 5; // Invalid, immutable.
}
}
Неявное (повторное) присвоение
На сегодняшний день назначение подполя структуры в C # 4.0 допустимо:
Vector v = new Vector(1, 2, 3);
v.Z = 5; // Legal in current C#.
Однако иногда компилятор может определить, когда к структурам по ошибке обращаются как к ссылкам, и запретит изменение подполей. Например, ( пример вопроса )
//(in a Windows.Forms context)
control.Size.Width = 20; // Illegal in current C#.
Поскольку Размер
является свойством, а Размер структуры
типом значения, мы будем редактировать копию / клон фактическое имущество, которое в таком случае было бы бесполезным. Как пользователи C #, мы склонны предполагать, что к большинству вещей доступ осуществляется по ссылке, особенно в проектах ООП, что заставляет нас думать, что такой вызов является законным (и это было бы, если бы размер структуры
был ] class
).
Кроме того, при доступе к коллекциям компилятор также запрещает нам изменять подполе структуры: ( пример вопроса )
List vectors = ... // Imagine populated data.
vectors[4].Y = 10; // Illegal in current C#.
Хорошая новость об этих досадных ограничениях заключается в том, что компилятор выполняет половину возможного агрегированного решения для таких случаев: обнаруживает, когда они возникают . Другая половина будет заключаться в неявном переназначении нового агрегата с измененным значением.
- В локальной области просто переназначьте вектор.
- Во внешней области найдите метод get, и если соответствующий метод доступа набора доступен, переназначить этому.
Чтобы это было сделано и во избежание путаницы, делегат должен быть помечен как неявный:
implicit aggregate Vector { ... }
implicit aggregate Size { ... }
// Example 1
{
Vector v = new Vector(1, 2, 3);
v.Z = 5; // Legal with implicit aggregates.
// What is implicitly done:
v = new Vector(v.X, v.Y, 5); // Local variable, simply reassign.
}
// Example 2
{
//(in a Windows.Forms context)
control.Size.Width = 20; // Legal with implicit aggregates.
// What is implicitly done:
Size old = control.Size.__get(); // External, MSIL detects a get.
// If MSIL can find a matching, accessible __set:
control.Size.__set({ 20, old.Height });
}
// Example 3
{
List vectors = ... // Imagine populated data.
vectors[4].Y = 10; // Legal with implicit aggregates.
// What is implicitly done:
Vector old = vectors[4].__get(); // External, MSIL detects a get.
// If MSIL can find a matching, accessible __set:
vectors[4].__set({ old.X, 10, old.Z });
}
// Example 4
{
Vector The5thVector(List vectors) { return vectors[4]; }
...
List vectors = ...;
The5thVector(vectors).Y = 10; // Illegal with implicit aggregates.
// This is illegal because the compiler cannot find an implicit
// "set" to match. as it is a function return, not a property or
// indexer.
}
Конечно, это последнее неявное переназначение является лишь синтаксическим упрощением, которое мог или не мог быть принят.
- Агрегаты (могли) быть неявно переназначены; См. Ответ и комментарий Марсело Кантоса.
- Агрегаты (могли) иметь интерфейсы;
- Агрегаты (могли) иметь методы;
Минусы
Поскольку агрегаты не заменяли бы структуры, а скорее были бы другой организационной схемой, я не могу найти много минусов, но надеюсь, что ветераны C # S / O смогут заполнить этот раздел CW. В заключение, пожалуйста, ответьте на вопрос напрямую, а также обсудите его: принесет ли C # преимущества агрегатным классам, как описано в этом посте? Я ни в коем случае не эксперт по C #, а только энтузиаст языка C # и пропускаю эту функцию, которая кажется мне важной. Мне нужен совет и комментарий опытных программистов по этому поводу. Я знаю, что существует множество обходных путей, и активно использую их каждый день , Я просто считаю, что они слишком распространены, чтобы их игнорировать.