powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / IDisposable и структуры
25 сообщений из 109, страница 1 из 5
IDisposable и структуры
    #40025330
listtoview
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
struct Disposable : IDisposable
{
    public bool Disposed { get; private set; }      
    public void Dispose() { Disposed = true; }
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
var d = new Disposable();
using (d)
{
      // Используем объект d
}
 
// Выведет: Disposed: false
Console.WriteLine("Disposed: {0}", d.Disposed);



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
var d = new Disposable();
 
{
    // Дополнительная область видимости для того, чтобы нельзя было 
    // использовать переменную, объявленную в блоке using за его пределами
    var tmp = d; try
    {
        // Тело блока using
    }
    finally
    {
        // Проверка на null для обычных (не-nullable) структур не нужна
        ((IDisposable)tmp).Dispose();
    }
}



значит ли это что память переменной d не будет освобождена?
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025335
listtoview
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и не понимаю зачем чз tmp сделано, все равно же finaly выполнится
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025351
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
listtoview
и не понимаю зачем чз tmp сделано, все равно же finaly выполнится

Написано же в комментарии

listtoview
память переменной d не будет освобождена?

Как это она может быть не освобождена, если это структура?
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025367
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
listtoview
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
var d = new Disposable();
using (d)
{
      // Используем объект d
}
 
// Выведет: Disposed: false
Console.WriteLine("Disposed: {0}", d.Disposed);



Потому что в блоке using произошёл boxing, и копия структуры залезла в кучу.
В переменной d ничего, понятное дело, не поменялось.

listtoview
значит ли это что память переменной d не будет освобождена?


Dispose не производит очистку памяти. Это просто метод с гарантией вызова при выходе из блока using.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025377
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Потому что в блоке using произошёл boxing, и копия структуры залезла в кучу.

Там нет боксинга. Просто внутри блока юзинг используется не сама структура, а её копия - вот оттуда и "странный" результат.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025383
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

Хм. И правда, боксинга нет, но это оптимизация компилятора.
Правильно считать, то боксинг есть, ибо он тут по всем правилам быть должен.
Соответственно поведение такое же, как если бы боксинг был.

((IDisposable)d).Dispose() -- эта хреновина однозначно приведёт к boxing структуры.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025393
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Хм. И правда, боксинга нет, но это оптимизация компилятора.

Это не совсем оптимизация. В IL есть ньюанс, что если виртуальный метод (из object) или метод интерфейса объявлены в самой структуре, то боксинга при их вызове не происходит. Очень, кстати, важная тема, потому что если методы object не переопределять в структуре, то можно получить боксинг там, где его совсем не ждешь (например, если у тебя структура это key в Dictionary<>, или элемент в HashSet<>). Кое-что детально можно найти погуглив про инструкцию IL "constrained".
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025460
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Это не совсем оптимизация. В IL есть ньюанс, что если виртуальный метод (из object) или метод интерфейса объявлены в самой структуре, то боксинга при их вызове не происходит.


Только в том случае, когда ты напрямую дёргаешь метод структуры, а не интерфейса.
using работает с интерфейсом IDisposable и про твою структуру ничего не знает.
Соответственно, должен быть boxing, так как требуется приведение к IDisposable.

Однако боксинга не происходит, это и есть оптимизация компилятора.

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

fkthat
Кое-что детально можно найти погуглив про инструкцию IL "constrained".


Если ты заменишь using на C# код, в который using разворачивается (try/finally), ты увидишь boxing.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025492
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сначала я видел этот вопрос на хабрец , но потом было интересно увидеть продолжение того как Сегрей Тепляков распедалил эту статью антихабрец
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025495
listtoview
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, зачем введена переменная tmp?
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025520
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
listtoview
Коллеги, зачем введена переменная tmp?


Это копия, чтобы гарантировать неизменность ссылки / значения.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025524
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub
Сначала я видел этот вопрос на хабрец , но потом было интересно увидеть продолжение того как Сегрей Тепляков распедалил эту статью антихабрец


Да ничего он особо там не "распедалил" и толком ничего не пояснил.
Характерен только странный наезд, типа лезете внуть дотнета ай-яй-яй!
Вопросы плохие задаёте!
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025530
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Только в том случае, когда ты напрямую дёргаешь метод структуры, а не интерфейса.

Вот, за интерфейс (особенно в случае с using) я действительно не уверен. Но в случае виртуального метода:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
var foo = new Foo();
var bar = new Bar();
foo.ToString();
bar.ToString();

internal struct Foo
{
    public override string ToString() => "I'm Foo!";
}

internal struct Bar
{
}



Код: il
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
entrypoint
.locals init (
       [0] valuetype Foo V_0,
       [1] valuetype Bar V_1
)

IL_0000: ldloca.s V_0
IL_0002: initobj Foo
IL_0008: ldloca.s V_1
IL_000a: initobj Bar
IL_0010: ldloca.s V_0
IL_0012: constrained. Foo
IL_0018: callvirt instance string [System.Runtime]System.Object::ToString()
IL_001d: pop
IL_001e: ldloca.s V_1
IL_0020: constrained. Bar
IL_0026: callvirt instance string [System.Runtime]System.Object::ToString()
IL_002b: pop
IL_002c: ret


Обрати внимание, что вызов один и тот же (строки 0012-0018 и 0020-0026), но, если верить талмуду, то боксинг, благодаря инструкции "constrained." будет только во втором случае. Я вот только в душе не знаю, как это реально проверить - вчера еще что-то об этом заморочился, но "правильного" способа так в голову и не пришло.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025552
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
как это реально проверить

Проверить, что в первом случае боксинга нет легко, но, вот, как убедиться, что он есть во втором случае - это вообще без понятия. Вызвать, что ли, ToString() стопятьсот раз и посмотреть потом, что там в куче лежит после этого, пока мусорщик еще её не уконрапупил - других идей у меня пока что нет.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025605
listtoview
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
listtoview
Коллеги, зачем введена переменная tmp?


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

да, это я понимаю
наверное лучше noLock заюзать
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025646
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
fkthat
как это реально проверить

Проверить, что в первом случае боксинга нет легко, но, вот, как убедиться, что он есть во втором случае - это вообще без понятия. Вызвать, что ли, ToString() стопятьсот раз и посмотреть потом, что там в куче лежит после этого, пока мусорщик еще её не уконрапупил - других идей у меня пока что нет.


Вот такая тула есть, но я не пробовал :)

https://www.codeproject.com/Articles/290247/BoxCop-Static-Assembly-Analyzer-tool
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025669
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Вот такая тула есть, но я не пробовал :)

У этого индуса в профиле написано: "A .net developer since 4+ years". Очешуеть, я говорить-то только лет после 3 начал, а люди в 4 уже на дотнет пишут.

Вот такой примитивнейший тестик:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
var foo = new Foo();

for (var j = 0; j < 10; j++)
{
    for (var i = 0; i < 100500000; i++)
    {
        foo.ToString();
    }

    Console.WriteLine(GC.GetTotalAllocatedBytes());
}

internal struct Foo
{
    public override string ToString() => null;
}




А теперь комментим перегрузку ToString()
Код: c#
1.
    // public override string ToString() => null;




Сразу видна разница, и видно, как эта разница с каждой итерацией растет.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025672
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Вот такой примитивнейший тестик:

А, кстати, добавил IDisposable и заменил foo.ToString() на using(foo) {} и роста кучи нет, как и в первом случае (с перегрузкой ToString). Т.ч. походу using тоже боксинг не вызывает, как сначала и ожидалось.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025687
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
fkthat
Вот такой примитивнейший тестик:

А, кстати, добавил IDisposable и заменил foo.ToString() на using(foo) {} и роста кучи нет, как и в первом случае (с перегрузкой ToString). Т.ч. походу using тоже боксинг не вызывает, как сначала и ожидалось.


Ну да, утиная оптимизация )
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025740
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Ну да, утиная оптимизация )

Вот тут несколько объясняется как это происходит:
https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-5.0 When a callvirt method instruction has been prefixed by constrained thisType, the instruction is executed as follows:

If thisType is a value type and thisType implements method then ptr is passed unmodified as the 'this' pointer to a call method instruction, for the implementation of method by thisType.

If thisType is a value type and thisType does not implement method then ptr is dereferenced, boxed , and passed as the 'this' pointer to the callvirt method instruction.

Т.е., если в IL такое:
Код: il
1.
IL_0012: constrained. Foo
IL_0018: callvirt instance string [System.Runtime]System.Object::ToString()
и у Foo есть своя реализация ToString, то CLR превращает callvirt в обычный call без боксинга.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025814
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
и у Foo есть своя реализация ToString, то CLR превращает callvirt в обычный call без боксинга.


И не выполняет виртуальный вызов.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025824
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

Единственное практическое применение, которое я вижу всей этой тряхомудии, это задрочить, унизить, и опустить кого-нибудь на собеседовании
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025826
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt,

Единственное практическое применение, которое я вижу всей этой тряхомудии, это задрочить, унизить, и опустить кого-нибудь на собеседовании


Вовсе нет. Честно говоря, вопросы про наследование интерфейса структурой многих приводит в недоумение. Этот вопрос хороший в нет плане, что ты ожидаешь правильный ответ, но можешь проследить логику размышлений.

Один из 20 человек может ответить на вопрос, чем отличается реализация GetHashCode() у классов и структур, так что -- это типа тоже унижение? :)
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025829
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
чем отличается реализация GetHashCode() у классов и структур

В смысле - дефолтная реализация? Я и сам не знаю - это надо исходники дотнета изучать Но, в чем будет разница с практической точки зрения, это я знаю.
...
Рейтинг: 0 / 0
IDisposable и структуры
    #40025831
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
hVostt
чем отличается реализация GetHashCode() у классов и структур

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


Зачем исходники дотнета? Это спека, вопрос же в принципиальном отличии, это довольно практический вопрос, а не какие-то там тонкие ньюансы для гуру.

Можно поговорить о том как работает GetHashCode() для классов, в контексте строения экземпляра класса в памяти, но мало с кем до этого вообще доходит :)
...
Рейтинг: 0 / 0
25 сообщений из 109, страница 1 из 5
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / IDisposable и структуры
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]