вернуть переменную, используемую для использования внутри с использованием C # - PullRequest
10 голосов
/ 13 мая 2010

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

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

Будет ли это уничтожать переменную свойств ??

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

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

Есть идеи?

Спасибо

Ответы [ 7 ]

10 голосов
/ 13 мая 2010

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

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

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

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

9 голосов
/ 13 мая 2010

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

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

7 голосов
/ 13 мая 2010

Предположительно, это шаблон для фабричного метода, который создает одноразовый объект. Но я все еще видел, как 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: Утилизировать объекты перед потерей области действия .

3 голосов
/ 13 мая 2010

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

Это будет прекрасно работать.

public DataTable foo ()
{
    DataTable properties = new DataTable();
    // do something
    return properties;
}
3 голосов
/ 13 мая 2010

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

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

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

1 голос
/ 13 мая 2010

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

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

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

0 голосов
/ 13 мая 2010

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

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

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

var user = GetNewUserInfo();
UsingDataContext(c => c.UserSet.Add(user));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...