Анонимные классы с именованными не доступными только для чтения типами в C #

1

В настоящее время я делаю что-то вроде:

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;

который кажется пустой тратой памяти, я предпочел бы получить имена и расстояния в одной структуре.

Но сама структура бессмысленна сама по себе, она используется только в алгоритме для вычисления.

  • 2
    Почему закрытый вложенный класс не работает? Если вам нужен такой одноразовый класс, ваша функция, вероятно, уже слишком велика и требует рефакторинга - и тогда вложенный класс будет правильным ...
  • 0
    Важны ли именованные переменные или важна проверка времени разработки переменных. Вы могли бы использовать dynamic но это не поможет вам во время разработки (без intelisense, без ошибок компилятора, если вы допустили ошибку)
Показать ещё 9 комментариев
Теги:

3 ответа

3

Нет - анонимные типы неизменяемы. Если вы хотите, чтобы изменяемый тип использовал класс (а не структуру). Использование dynamic и ExpandoObject будет одной из альтернатив, но вы потеряете безопасность типа времени разработки.

Если вы укажете еще какой-то контекст, как они используются, могут быть другие альтернативы.

1

Чтобы обеспечить аналогичное решение как 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

Но, как я сказал в комментарии выше, вы действительно не можете использовать анонимный тип, если вам нужно ссылаться на тип в объявлении словаря. Вы можете использовать кортеж, но в целом вы получаете гораздо большую гибкость, если просто вводите собственный тип. Например, если вы решите, что вам нужно другое значение там (по какой-либо причине), вы можете просто добавить его без всякого взлома. Если вы, с другой стороны, используете кортеж или что-то подобное, вам придется обновлять каждое его использование.

  • 0
    Спасибо, тыкаешь, как мне объявить словарь этого типа без необходимости сначала создавать элементы?
1

Одна из возможностей, как вы сказали, используя 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...

  • 0
    Этот хак выглядит довольно круто :)
  • 0
    Хотя вся цель состояла в том, чтобы избежать «неестественного» вложенного класса :)
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню