Возвращает переменную, используемую для использования внутри С#

Я возвращаю переменную, которую я создаю в операторе using внутри оператора using (звучит смешно):

public DataTable foo ()
{
    using (DataTable properties = new DataTable())
    {
       // do something
       return properties;
    }
}

Будет ли это Dispose изменена переменная??

После этого я все равно получаю это предупреждение:

Предупреждение 34 CA2000: Microsoft.Reliability: в методе test.test вызовите System.IDisposable. Задайте свойства объекта перед тем, как все ссылки на него выходят за рамки.

Любые идеи?

Спасибо

Ответ 1

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

Вам нужно создать его таким образом:

public DataTable Foo() 
{ 
    DataTable properties = new DataTable();
    return properties; 
} 

и назовите Dispose() на нем позже.

Ответ 2

Да, он будет распоряжаться им, а затем вернуть его. Это почти всегда плохо.

Фактически для DataTable, Dispose почти никогда ничего не делает (исключение, если оно где-то удалено, IIRC), но оно по-прежнему в целом плохая идея. Обычно вы должны рассматривать расположенные объекты как непригодные для использования.

Ответ 3

Предположительно, это шаблон для метода factory, который создает одноразовый объект. Но, я все еще видел, что Code Analysis также жалуется на это:

        Wrapper tempWrapper = null;
        Wrapper wrapper = null;

        try
        {
            tempWrapper = new Wrapper(callback);
            Initialize(tempWrapper);

            wrapper = tempWrapper;
            tempWrapper = null;
        }
        finally
        {
            if (tempWrapper != null)
                tempWrapper.Dispose();
        }

        return wrapper;

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

Статья MSDN: CA2000: удалять объекты до потери области.

Ответ 4

Да. Почему вы используете ключевое слово using на том, что вы не хотите размещать в конце блока кода?

Цель ключевого слова using заключается в удалении объекта.

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Ответ 5

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

Это будет работать нормально.

public DataTable foo ()
{
    DataTable properties = new DataTable();
    // do something
    return properties;
}

Ответ 6

Ваш код, используя ключевое слово using, расширяется до:

{
    DataTable properties = new DataTable();
    try
    {
        //do something
        return properties;
    }
    finally
    {
        if(properties != null)
        {
            ((IDisposable)properties).Dispose();
        }
    }
}

Ваша переменная утилизируется по характеру использования работ. Если вы хотите вернуть свойства, не помещайте их в используемый блок.

Ответ 7

Другие ответы верны: как только вы выходите из блока использования, ваш объект удаляется. Использованный блок отлично подходит для того, чтобы обеспечить своевременное размещение объекта, поэтому, если вы не хотите полагаться на потребителей своей функции, чтобы помнить об удалении объекта позже, вы можете попробовать что-то вроде этого:

public void UsingDataContext (Action<DataContext> action)
{
    using (DataContext ctx = new DataContext())
    {
       action(ctx)
    }
}

Таким образом вы можете сказать что-то вроде:

var user = GetNewUserInfo();
UsingDataContext(c => c.UserSet.Add(user));