im trying some different approach. Im not sure if its possible to place using() statement above methods or is there other way around.
public class Main
{
public Main()
{
using(Type t = new Type)
{
public void SomeFunction() {
t.toString()}
}
}
}
That is not possible, but you can do that like this:
using(Type t = new Type)
{
SomeFunction(t);
}
public void SomeFunction(Type tType)
{
tType.ToString();
}
Note : The t will be transferred to SomeFunction() and will be disposed at } of using block if the Class Type implements IDisposible, Since Using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called
Related
This question already has answers here:
What happens if i return before the end of using statement? Will the dispose be called?
(5 answers)
Closed 4 years ago.
While working on my project, I was wondering, will using auto-destruct data if return will be inside of a using.
Example block of code:
using(ManagedObject obj = new ManagedObject())
{
int usualNumber = 0;
// some magic stuff
...
// magic stuff ends
return usualNumber; // return goes inside of 'using' brackets
}
And here is the question, will our ManagedObject which implements IDisposable be disposed by 'using' statement?
using statement can be seen as try and finally combination.
Your code is equivalent to:
ManagedObject obj = new ManagedObject();
try
{
int usualNumber = 0;
// some magic stuff
...
// magic stuff ends
return usualNumber;
}
finally
{
if (obj != null)
((IDisposable)obj ).Dispose();
}
I assume, that the answer to your question can be seen thanks to this code sample.
using is a Syntactic sugar, it need to contain an object which implements IDisposable interface when you leave the using scope .net will call the IDisposable.Dispose method Automatically.
Here is a sample c# online
when the program leave Test method. .net will call IDisposable.Dispose method Automatically
Yes, It will call the Dispose() function implemented by the IDisposable interface
class Program
{
static void Main(string[] args)
{
new Test().TestIt();
Console.Read();
}
}
class Test
{
public int TestIt()
{
using (ManagedObject obj = new ManagedObject())
{
int usualNumber = 0;
return usualNumber;
}
}
}
internal class ManagedObject : IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
Yes, even if you return from inside the using block, it will still call Dispose on obj.
Note that returning the usualNumber is perfectly fine, but if you were to return obj, that could be a problem because you would be returning a "disposed" object.
(Technically, objects could be usable after calling Dispose. For example, you could implement a Dispose that does nothing. But generally, most Dispose implementations would put the object in an unusable state).
Imagine this snippet:
using System;
public class Report {
static int Level=0;
public static void WriteLine(string Message) {
Console.WriteLine("{0}{1}",new String(' ',4*Level),Message);
}
public class Indent:IDisposable {
public Indent() { Report.WriteLine("{"); ++Level; }
void IDisposable.Dispose() { --Level; Report.WriteLine("}"); }
}
}
class Program {
static void Main() {
Report.WriteLine("Started");
Report.WriteLine("Calling submethod");
using(new Report.Indent()) {
Report.WriteLine("Submethod started");
using(new Report.Indent()) Report.WriteLine("Subsub, maybe?");
Report.WriteLine("Submethod reporting everything is fine");
Report.WriteLine("Submethod finished");
}
Report.WriteLine("Finished");
}
}
Which produces result:
Started
Calling submethod
{
Submethod started
{
Subsub, maybe?
}
Submethod reporting everything is fine
Submethod finished
}
Finished
Inside I'm using using(new Report.Indent()) instead of sticking to the only documented version I found, i.e. using(Report.Indent r=new Report.Indent()).
In my briefer version, however, can I be sure that Dispose() will always be called on those unnamed Indent objects, every time?
P.S.
// btw, I used word "anonymous" in the title, but I'm not sure that's what new objects that aren't assigned to any named variable should be called
Yes, using enures that even "anonymous objects" are always disposed of.
Internally, using stores whatever value was used when entering the block in local variable. This stored value is disposed when exiting the block.
Im trying to hunt down a race condition, and I come across a lot of suspecious functions. Most of them are not allowed to be called from two threads at the same time, but its hard to make sure they don't.
Is there some keyword to instruct the runtime to throw an exception as soon as a function is executing in parallel? I know I sometimes get an exception when another thread modifies a collection which im enumerating, but are safeguards like that enough to rely on?
The runtime can halt execution using the lock instruction, so all I need is a lock which throws an error.
You can use Monitor.TryEnter for this:
bool entered = !Monitor.TryEnter(someLockObject);
try
{
if (!entered)
throw Exception("Multi-thread call!");
// Actual code
}
finally
{
if (entered)
{
Monitor.Exit(someLockObject);
}
}
And it would be good to wrap that code in its own class:
public sealed class MultiThreadProtector : IDisposable
{
private object syncRoot;
public MultiThreadProtector(object syncRoot)
{
this.syncRoot = syncRoot;
if (!Monitor.TryEnter(syncRoot))
{
throw new Exception("Failure!");
}
}
public void Dispose()
{
Monitor.Exit(this.syncRoot);
}
}
This way you can execute it as follows:
using (new MultiThreadProtector(someLockObject))
{
// protected code.
}
I'm currently working on a C# program that creates a List, of object Task, the object Task is a base class and many other inherit from it. What I want to is compare the type of one of the object within said list to see which form should be opened in order to edit it.
This is the code I have already created.
private void itemEdit_Click(object sender, EventArgs e)
{
int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
if(checkTask.GetType is Note)
{
noteBuilder editNote = new noteBuilder(todoList);
editNote.Show();
}
else if(checkTask.GetType is extendedTask)
{
extendedTaskBuilder editTask = new extendedTaskBuilder(todoList);
editTask.Show();
}
else if(checkTask.GetType is Reminder)
{
reminderBuilder editReminder = new reminderBuilder(todoList);
editReminder.Show();
}
else if (checkTask.GetType is Appointment)
{
appointmentBuilder editAppointment = new appointmentBuilder(todoList);
editAppointment.Show();
}
}
On a secondary note would it be easier if instead of passing the list between the forms and generating a new object of the form that display information that I instead pass a single object between forms and just update the form every time a new element is added to the list.
Many thanks
Have you tried checking like this:
if (checkTask is Note)
{
}
...
Have you considered creating a base class for all types you are now switching between and call a virtual (abstract) method?
Put all code now in the if in the overridden abstract method.
Advantages:
- The intelligence of the switch is within the classes where it belongs.
- When a new type is added you get a compiler error to also add this feature to the new type.
I suggest that instead of doing that series of ‘if’ clauses, you use inheritance to achieve what ou need. First you create a virtual method in your base class. A virtual method means it won't have any implementation in the base class, only the declaration:
public class Task
{
(...)
public virtual void ShowEditForm(IList todoList);
(...)
}
Then you create the child class methods (I'm assuming the todoList object is a IList, but just change it if it is not).
public class Note: Task
{
(...)
public override void ShowEditForm(IList todoList)
{
(new noteBuilder(taskToEdit)).Show();
}
(...)
}
public class Reminder: Task
{
(...)
public override void ShowEditForm(IList todoList)
{
(new reminderBuilder(taskToEdit)).Show();
}
(...)
}
I didn't write all the classes, but I think you've got the idea. To call the method, you just call the method from Task class, and the right method will be executed:
int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
checkTask.ShowEditForm(todoList);
This way, when you want to create new types of Task, you just have to create the child class, with the proper method, and the inheritance system will do the rest.
One more thing, the override keyword in the child method declaration is important, because it says to the compiler that this method should be called even if you call it from the BaseClass.
First, to your second note. What you are talking about doing is having a global object that all forms refer to in some parent. That can work, however you will need to make sure there is some mechanism in place that makes sure all of the forms are synchronized when one changes, and this can get messy and a bit of a mess to maintain. I am not necessarily advocating against it per say, but just adding words of caution when considering it :)
As to your posted code, it would probably be better to turn this into a Strategy Pattern approach, where all forms inherit from a base class/interface which has a Show method. Then all you need to do is call checkTask.Show(todoList);. If you do not want that coming from the Task, then you could have your forms all inherit from the above base and you could use a factory pattern that takes in the Task and list and returns the appropriate form on which you simply call form.Show();
Code like this is difficult to maintain, you are probably better off abstracting this out, like so (assuming Task is not the one included in .net):
public interface IBuilder
{
void Show();
}
public abstract class Task
{
// ...
public abstract IBuilder GetBuilder(TaskList todoList);
// ...
}
public class Note : Task
{
public override IBuilder GetBuilder(TaskList todoList)
{
return new noteBuilder(todoList);
}
// ...
}
// etc.
private void itemEdit_Click(object sender, EventArgs e)
{
int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
IBuilder builder = checkTask.GetBuilder(todoList);
builder.Show();
}
Alternately, you can use an injection pattern:
public abstract class Task
{
protected Task(Func<TaskList, IBuilder> builderStrategy)
{
_builderStrategy = builderStrategy;
}
public IBuilder GetBuilder(TaskList todoList))
{
return _builderStrategy(todolist);
}
}
public class Note : Task
{
public Note(Func<TaskList, IBuilder> builderStrategy) : base(builderStrategy) {}
}
// ...
note = new Note(x => return new noteBuilder(x));
I was recently going through a garbage collection article and decided to play along and attempt to gain a greater understanding. I coded the following, playing around with the using statement, but was surprised with the results... I expected e.Parent.Name outside of the using block to go ka-blooey.
What exactly is going on here?
static void Main(string[] args)
{
Employee e = new Employee();
using (Parent p = new Parent())
{
p.Name = "Betsy";
e.Parent = p;
Console.WriteLine(e.Parent.Name);
}
Console.WriteLine(e.Parent.Name);
Console.ReadLine();
}
public class Employee
{
public Parent Parent;
}
public class Parent : IDisposable
{
public string Name;
public void Dispose()
{
Console.WriteLine("Disposing Parent");
}
}
Your Dispose method doesn't actually do anything to the instance of Parent, hence it's still fair game / works as a usable instance of a class.
IDisposable is usually used when your class holds onto an unmanaged resource, such as a database connection or a file, so that it can be cleaned up when Dispose() is called. Just calling Dispose doesn't do anything to the unmanaged resources, there has to be some code in the method that does something to those resources. Whilst c# might have the using() {} syntax to wrap instantiation and disposal of an IDisposable object in a try/catch/finally, it doesn't mean it does anything "special" with the disposed object.
Imagine, hypothetically, that Name is actually an unmanaged resource, rather than just a string, your Dispose() method could read:
public void Dispose()
{
Name = null;
Console.WriteLine("Disposing Parent");
}
Because you've assigned p to e.Parent, the object itself is still "in scope" as there's a reference to it, hence it's still accessible for Console.WriteLine(e.Parent.Name); to produce output from.
It's also currently "CLR Week" over at The Old New Thing and the first 3 articles of the week are discussing the Garbage Collector and how it works/behaves. They're well worth a read:
Everybody thinks about garbage collection the wrong way
When does an object become available for garbage collection?
Everybody thinks about CLR objects the wrong way (well not everybody)
IDisposable.Dispose is intended for you to use it to clean up unmanaged resources that you own (like file handles etc.) It doesn't do anything in its own right. The most common usage is if your class had member variables that implement IDisposable themselves, you now have responsibility for Dispose'ing them. It's just a pattern to help you, and has nothing to do with Garbage Collection - quite the opposite in fact.
The Dispose method does not destroy the object from memory. Normally a dispose method will only free up resources that it created.
Since e still exists in scope that anything associated with e (the parent assigned to e) will still exist until e is out of scope.
IDisposable is not a language feature, and does nothing special in the runtime. It is just an interface/method like any other. It happens to be a useful pattern, so they added syntax to automatically call that method in a specific pattern (using), and there are special exceptions you can throw that have "Dispose" in their name (like ObjectDisposedException).
using blocks turn from this:
using(SomeType t = new SomeType())
{
t.Something();
}
into something like this:
{
SomeType t;
try
{
t = new SomeType();
t.Something();
}
finally
{
t.Dispose();
}
}
There is absolutely no way to force the GC to collect anything. If there are references to your object somewhere in the stack (ignoring unsafe and C++/CLI code), or chained references to it from some object on the stack, then your object will live.
If you want that code to blow up, you can do something like this:
public class Parent : IDisposable
{
public string Name
{
get
{
AssertNotDisposed();
return name;
}
set
{
AssertNotDisposed();
name = value;
}
}
public void Dispose()
{
AssertNotDisposed();
Console.WriteLine("Disposing Parent");
isDisposed = true;
}
private void AssertNotDisposed()
{
if(isDisposed)
throw new ObjectDisposedException("some message");
}
private string name;
private bool isDisposed = false;
}
If you're looking for another example that will blow up when trying to do something to a disposed object.
static void Main(string[] args)
{
Employee e = new Employee();
using (Parent p = new Parent("test.txt"))
{
e.Parent = p;
using ( System.IO.StreamWriter fileWriter =
new System.IO.StreamWriter(e.Parent.File))
{
fileWriter.WriteLine("Betsy");
}
}
using (System.IO.StreamWriter fileWriter =
new System.IO.StreamWriter(e.Parent.File))
{
fileWriter.WriteLine("Betsy"); //uh-oh
}
Console.ReadLine();
}
public class Employee
{
public Parent Parent;
}
public class Parent : IDisposable
{
public System.IO.FileStream File;
public Parent(string fileName)
{
File = System.IO.File.Open(fileName, System.IO.FileMode.OpenOrCreate);
}
public void Dispose()
{
((IDisposable)File).Dispose(); //or File.Close();
}
}