Подтвердить что ты не робот

Можно ли определить локальную структуру внутри метода в С#?

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

Я часто использую структуры для создания кода, который почти сам документируется в местах. Однако С# заставляет меня определять структуру вне метода. Это нарушает вышеупомянутую передовую практику - ее в основном создает нежелательный глобальный тип переменной для всего класса.

Можно ли определить локальную структуру внутри метода, точно так же, как локальную переменную, а если нет, можете ли вы дать мне окно по причинам, которые разработчики С# решили предотвратить?

Пример использования

Я конвертирую часть таблицы в код С#. Я хотел бы использовать локальные структуры внутри метода для хранения временной информации организованным образом, не прибегая к сотням отдельных переменных, которые являются глобальными по объему.

Обновление - С# 7.0 может иметь эту функцию!

По состоянию на 2016-августа, по-видимому, это будет особенностью в С# 7.0.

Итак, команда компилятора С# согласилась - ничего себе!

4b9b3361

Ответ 1

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

Однако вы можете определить переменные анонимного типа в методе. Это будет несколько напоминать структуры. Компромисс.

public void SomeMethod ()
{
    var anonymousTypeVar = new { x = 5, y = 10 };
}

Ответ 2

Вы можете сделать что-то подобное, используя анонимные типы. Примеры MSDN ниже:

var v = new { Amount = 108, Message = "Hello" };

или

var productQuery = 
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

Ответ 3

Немного поздно, но это мое решение для списков - использование анонимных vars как структур внутри методов:

var list = new[] { new { sn = "a1", sd = "b1" } }.ToList(); // declaring structure
list.Clear();                                               // clearing dummy element
list.Add(new { sn="a", sd="b"});                            // adding real element
foreach (var leaf in list) if (leaf.sn == "a") break;       // using it

Анонимные элементы (sn и sd) как-то читаются.

Ответ 4

Нет, это невозможно. Если вы используете .net 4.0, вы можете использовать Tuple<T1, ..., Tn> для репликации такой вещи.

Я не вижу причины, по которой вам нужна такая структура, просто используйте переменные с именами говорящих, и это не должно быть проблемой вообще. В сочетании с явным объявлением с использованием имен классов очень мало места для двусмысленности.

Ответ 5

Нет, это невозможно. Какое практическое применение? Как часто полезно использовать структуру только в рамках одного метода. Microsoft, вероятно, не видит веских оснований для реализации этой функции. В тех случаях, когда это может быть полезно, мы имеем анонимные типы и анонимные методы.

Ответ 6

Вы можете определить анонимный тип в своем методе и использовать его. Анонимный тип будет только для чтения, поэтому он дает вам неизменность, которая требуется для структур. Он явно не будет структурой, но будет полностью определен и содержаться в вашем методе.

var myLocalType = new 
    {
        SomeValue = "Foo",
        SomeId = 14
    };

Ответ 7

это не структура, но mayme var может помочь вам здесь?

var person = new {Name= "John", City = "London"};

он сильно напечатан, поэтому будет проверяться время компиляции

Ответ 8

Вы можете создать динамический тип в С# 4.0 для выполнения этой задачи, но это не совсем то, что вы ищете.

Однако я считаю, что максимум определения переменных, близких к тому, где они используются, означает, что переменная вводится в поток программы не там, где объявлен тип. Я считаю, что большинство типов имеют некоторую способность к повторному использованию, создавая в типах типов ограничения, позволяющие создавать многоразовые блоки кода, которые работают с общими данными.