В настоящее время я делаю что-то вроде:
public class UselessClass
{
public string x;
public int y;
}
Я использую этот класс только один раз в функции...
Dictionary<string, UselessClass> dict;
Я хотел бы иметь возможность редактировать значения UselessClass, поэтому я считаю, что Tuple недостаточно, поскольку они доступны только для чтения после создания. Я также хотел бы, чтобы именованные переменные x и y выполняли такие вещи, как:
dict["hello"].y++;
Могу ли я сделать это без необходимости использовать этот UselessClass вокруг кода, когда он действительно используется только один раз для функции? Какой-то анонимный класс с именованными переменными?
Чтобы добавить дополнительные сведения:
Это чисто используется в алгоритмической функции, где я хочу соединить строку с определенными переменными, а именно другую строку x и целое число, представляющее расстояние
Лучший способ, я могу думать о добавлении свойств к уже существующему классу, например string, - это использовать словарь.
Вместо того, чтобы делать:
Dictionary<string, string> names;
Dictionary<string, int> distances;
который кажется пустой тратой памяти, я предпочел бы получить имена и расстояния в одной структуре.
Но сама структура бессмысленна сама по себе, она используется только в алгоритме для вычисления.
Нет - анонимные типы неизменяемы. Если вы хотите, чтобы изменяемый тип использовал класс (а не структуру). Использование dynamic
и ExpandoObject
будет одной из альтернатив, но вы потеряете безопасность типа времени разработки.
Если вы укажете еще какой-то контекст, как они используются, могут быть другие альтернативы.
Чтобы обеспечить аналогичное решение как terrybozzio, хотя и менее хакерское (использование одноэлементного массива не так уж и хорошо), вы также можете использовать оболочку, которая делает тип изменчивым:
class Mutable<T>
{
public Mutable(T value)
{
Value = value;
}
public T Value { get; set; }
}
Вы могли бы даже использовать это для анонимных типов:
var x = new {
Foo = "Bar",
Baz = new Mutable<int>(2)
};
Console.WriteLine(x.Baz.Value); // 2
x.Baz.Value++;
Console.WriteLine(x.Baz.Value); // 3
Но, как я сказал в комментарии выше, вы действительно не можете использовать анонимный тип, если вам нужно ссылаться на тип в объявлении словаря. Вы можете использовать кортеж, но в целом вы получаете гораздо большую гибкость, если просто вводите собственный тип. Например, если вы решите, что вам нужно другое значение там (по какой-либо причине), вы можете просто добавить его без всякого взлома. Если вы, с другой стороны, используете кортеж или что-то подобное, вам придется обновлять каждое его использование.
Одна из возможностей, как вы сказали, используя Tuple, но поскольку их элементы не могут быть изменены, вы можете немного "взломать", если хотите называть это объявлением Tuple<int[],string[]>
поэтому, когда вы добавляете элемент в словарь вы создаете экземпляр кортежа, но с одним элементом в каждом массиве, который можно манипулировать:
Dictionary<string,Tuple<int[],string[]>> test = new Dictionary<string, Tuple<int[],string[]>>();
//here i add a new dict entry and to the int[] i assign the value 5.
test.Add("test1", new Tuple<int[], string[]>(new int[1]{5}, new string[1]));
test["test1"].Item1[0]++;
test["test1"].Item1[0]++;
//here the int will be 7.
Хотя я бы пошел с UselessClass...
dynamic
но это не поможет вам во время разработки (без intelisense, без ошибок компилятора, если вы допустили ошибку)