Ответ Ceilingfish может быть технически правильным, но он рекомендует использовать пробел в конце строки. Это подвержено ошибкам и не является хорошей практикой!
Вот как я бы это сделал:
Создайте файл settings.yaml со следующим содержимым:
---
feeds:
:url: 'http://www.google.com'
:label: 'default'
Это создаст следующий хеш после загрузки файла YAML:
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> YAML.load_file('settings.yaml')
=> {"feeds"=>{:url=>"http://www.google.com", :label=>"default"}}
irb(main):003:0>
В этом примере я также использую символы, так как это, кажется, предпочтительный способ хранения ключей Ruby в Ruby.
Dispose не вызывается автоматически; вам нужно вызвать его или использовать блок using, например
using(Stream s = File.OpenRead(@"c:\temp\somefile.txt"))
// Do something with s
GC вызывает финализатор, только если он существует. Наличие финализатора приводит к тому, что ваш класс будет собран в 2 этапа; сначала объект помещается в очередь финализатора, затем вызывается финализатор и объект собирается. Объекты без финализаторов собираются напрямую.
Рекомендация состоит в том, что Dispose избавляется от управляемых и неуправляемых ресурсов, а финализатор очищает только неуправляемые ресурсы. Когда метод Dispose освободил неуправляемые ресурсы, он может вызвать GC.SuppressFinalize, чтобы объект не прожил долго и не помещался в очередь финализатора. См. MSDN для правильного образца шаблона удаления.
Как и в крайнем случае ... вы можете создавать объекты вообще без использования ctor:
class Foo {
public Foo() {
message += "; ctor";
}
string message = "init";
public string Message { get { return message; } }
}
static class Program {
static void Main() {
Foo foo = new Foo();
Console.WriteLine(foo.Message); // "init; ctor"
Foo bar = (Foo)System.Runtime.Serialization.FormatterServices
.GetSafeUninitializedObject(typeof(Foo));
Console.WriteLine(bar.Message); // null
}
}
Вот шаги, о которых я знаю:
Как уже указали другие, Dispose ()
должен быть вызывается пользователем, поскольку среда выполнения не будет его обрабатывать.
Здесь - подробное описание вопроса. Во-первых, Dispose не вызывается средой выполнения, вы должны вызывать его самостоятельно. Также нет деструкторов, но есть финализаторы: если объект переопределяет метод Finalized, он вызывается, когда объект больше не доступен для приложения. Может случиться так, что во время финализации объект снова станет доступным (например, сохраняет ссылку на себя в глобальном объекте), поэтому он вернется к шагу 2 вашей модели. В объекте GC также есть методы, которые позволяют пользователю завершить завершение объекта управления.
Замечание о конструкторе:
Каждый класс имеет один, так как один будет сгенерирован компилятором, если вы не запрограммируете его самостоятельно. И первое, что это делает (если не указано иное), - это вызов ctor его родительского типа.
0) Если статический конструктор существует на объекте, он вызывается в первый раз, и объект этого типа создается или на него ссылаются
В C # инициализаторы членов вызываются перед конструктором, а в VB.NET они вызываются после конструктора.
Среда выполнения не гарантирует вызова Finalize
в все.
Dispose и Finalize предназначены только для очистки неуправляемых ресурсов. Попытка очистить управляемые ресурсы в финализаторе путем, например, вызова Dispose для внутренних членов, приведет к проблемам, потому что они, возможно, уже были завершены.
Мне нравится сохранять простоту и просто использовать финализатор для обнаружения и регистрации неприятных ошибок сообщение, предлагающее разработчику исправить код. Попытка выяснить, безопасно ли выполнять работу, которую должна была выполнять Dispose
, слишком легко ошибиться, и обычно не стоит тратить на нее циклы.
Вот пример класса, который использует всю информацию, доступную в статьях, представленных здесь. Я уже потратил часы на тестирование, и это то, что лучше всего подходит для меня.
/*********************************
* Author: Theofanis Pantelides *
* Date: 23 Jun 2009 *
*********************************/
using System;
using System.IO;
public class MyClass : IDisposable
{
String oFile;
Stream oStream;
public MyClass(String _File)
{
oStream = File.OpenRead(oFile = _File);
// Initialize
}
~MyClass()
{
this.Dispose();
// Destruct
}
public void doSomething()
{
// do Whatever it is you are trying to do
}
#region IDisposable Members
/// <summary>
/// Dispose all resources used by instance of class
/// and update Garbage Collector information
/// </summary>
public void Dispose()
{
if (oStream != null)
{
oStream.Dispose(); // Dispose using built in functions
GC.SuppressFinalize(oStream); // No need for Garbage Collector
}
oStream = null; // Nullify it.
}
#endregion
}
Использование:
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
Вы даже можете использовать одно и то же объявление дважды, так как оно не существует за пределами 'using'.
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}