Seeking best inputs on correct usage of C# using statement. Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?
Although the code snippet is different from what I feel that the using statement should be in ProcessFileAndReturnNumberFromStream() method of 'Business' class.
Why is it an uncommon practice to use using statement on object passed via parameter? Please correct or elaborate on the flaw?
using System;
using System.IO;
class Data
{
public double? GetNumberFromStream(StreamReader sr)
{
double? number;
try
{
using (sr)
{
number = Convert.ToDouble(sr.ReadToEnd());
return number;
}
}
finally
{
number = null;
}
}
}
class Business
{
public double? ProcessFileAndReturnNumberFromStream()
{
string fileName = "Test.txt";
StreamReader sr = new StreamReader(fileName);
Data dat = new Data();
return dat.GetNumberFromStream(sr);
}
}
class GUI
{
static void Main()
{
Business bus = new Business();
double? number = bus.ProcessFileAndReturnNumberFromStream();
Console.WriteLine(number);
Console.ReadKey();
}
}
Please help.
Thanks
If a method is passed an object that implements IDisposable, it's usually the responsibility of the caller to manage the lifetime of that object, rather than the callee.
public double? ProcessFileAndReturnNumberFromStream()
{
string fileName = "Test.txt";
Data dat = new Data();
using (StreamReader sr = new StreamReader(fileName))
{
return dat.GetNumberFromStream(sr);
}
}
The caller that is passing the instance of IDisposable should be the one to use the using statement. If the callee uses it, the object will be disposed while outside the immediate control of the caller who 'owns' the object.
Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?
You can, but it's generally odd to do so. Usually whatever is creating the StreamReader would be expecting to "own" it and dispose of it when they're done with it. It would be more usual for your ProcessFileAndReturnNumberFromStream method to be:
using (StreamReader sr = new StreamReader(fileName))
{
Data dat = new Data();
return dat.GetNumberFromStream(sr);
}
(Although I'd personally use File.OpenText instead of explicitly constructing the StreamReader.)
Your GetNumberFromStream method would then not need the using statement. It also doesn't need the try/finally block at all - it's an odd implementation all round, given that it will never return null, either...
It's also odd that you're creating a new instance of Data and then doing nothing with it - as your GetNumberFromStream method doesn't use an instance variables or override a base class method, you should consider making it static.
Such API would be extremely troublesome.
You would never know whether or not the object passed to a method is disposed inside the method or not. Thus, if this is you who create the object and pass it there, you would also never know whether or not you should dispose the object you have just created and passed to the method or not.
I guess then, while this is technically possible, it would promote the bad programming style.
Related
I have this code that queries a database. I want to put the actual database code into a separate class so I can reuse it in other places. This will leave just the actual read of the PassResult value so I can make a Unit Test of the code without having the SQL code running. I am having trouble finding references on how to make this kind of code Unit Testable. Could someone help out?
using System;
using System.Data;
using System.Data.SqlClient;
namespace CS_UI_Final_Inspection
{
public class CalibrationTestCheck
{
// declare the variables
private bool _calibrationTestPass = false;
private string _connectionString = string.Empty;
public bool CheckCalibrationTestResults(string serialNumber, IDeviceInfo deviceInfo, string mapID)
{
// get database location
DhrLocationPull dhrLocation = new DhrLocationPull();
_connectionString = dhrLocation.PullDhrLocation();
// build the query
SqlConnection calibrationCheckConnection = new SqlConnection(_connectionString);
SqlCommand calibrationCheckCommand = new SqlCommand("[MfgFloor].[GetLatestTestResultsForDeviceByTestType]",
calibrationCheckConnection);
// build the stored proc
calibrationCheckCommand.CommandType = CommandType.StoredProcedure;
calibrationCheckCommand.Parameters.Add(new SqlParameter("#SerialNumber", serialNumber));
calibrationCheckCommand.Parameters.Add(new SqlParameter("#DeviceTypeID", mapID));
calibrationCheckCommand.Parameters.Add(new SqlParameter("#TestDataMapTypeID", "C"));
calibrationCheckCommand.Connection.Open();
SqlDataReader calibrationCheckReader = calibrationCheckCommand.ExecuteReader();
// is there data?
if (calibrationCheckReader.HasRows)
{
// read the data
calibrationCheckReader.Read();
try
{
_calibrationTestPass = (bool) calibrationCheckReader["PassResult"];
}
catch (InvalidOperationException)
{
// means last element was not filled in
}
finally
{
// close refs
calibrationCheckReader.Close();
calibrationCheckCommand.Connection.Close();
calibrationCheckConnection.Close();
calibrationCheckReader.Dispose();
calibrationCheckCommand.Dispose();
calibrationCheckConnection.Dispose();
}
}
return _calibrationTestPass;
}
}
}
create an interface and implement it.
move all references to be tested to use the interface (exposing any methods/properties required through the interface)
have the constructor or method being tested take the interface as a parameter.
Roy Oscherov is a good resource on this. Roy Oscherov wrote a great book called "The art of unit testing". Roy's website can be found here: http://osherove.com/
The C# reference manual defines the syntax of using statements as:
using-statement:
using ( resource-acquisition ) embedded-statement
resource-acquisition:
local-variable-declaration
expression
Can someone provide me with an example that uses an expression inside using statement.
Conventional examples are using a variable declaration.
An example of using an expression is as follows:
var stream = new MemoryStream();
using(stream)
{
//Perform operations with stream here.
}
//Stream is now disposed.
Here, the stream variable is declared outside the using, but wrapped by the using. It will then dispose the stream variable upon completion.
This isn't a very common pattern, but it is useful for where you may need to perform other operations on the resource after it has been disposed of.
This can be used with method calls, etc. Essentially any expression that evaluates to a type of IDisposable can be used. Generally, not having access to the IDisposable inside the using statement isn't that useful.
The only scenario where I have seen it used this way is in ASP.NET MVC with the form helpers such as.
#using(Html.BeginForm())
{
#Html.TextBox("Name");
}
An example:
//Create the file.
using (FileStream fs = File.Create(path))
{
AddText(fs, "This is some text");
AddText(fs, "This is some more text,");
AddText(fs, "\r\nand this is on a new line");
AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");
for (int i=1;i < 120;i++)
{
AddText(fs, Convert.ToChar(i).ToString());
}
}
Explanation:
Provides a convenient syntax that ensures the correct use of IDisposable objects.
The using statement calls the Dispose method on the object at the and of the block.
It will call the Dispose method even if an Exception is thrown.
The key thing to look at is actually the definition of local-variable-declaration from section 8.5.1
A local-variable-declaration declares one or
more local variables.
local-variable-declaration: local-variable-type
local-variable-declarators
local-variable-type: type var
local-variable-declarators:
local-variable-declarator local-variable-declarators , local-variable-declarator
local-variable-declarator: identifier
identifier = local-variable-initializer
local-variable-initializer: expression array-initializer
So a local-variable-declaration could be expressed as type identifer = expression. So what the specification for using is telling you is you can either declare a variable in the form var variableName = xxxxxxx or you can just use the xxxxxx part by itself.
Another example of expression that I don't see mentioned here is:
IDisposable disposable;
using (disposable = new SomeDisposableObject()) {
// do something
}
or
IDisposable disposable;
using (disposable = SomeExpressionOrFunctionThatEvaluatesToADisposable()) {
// do something
}
The reference doesn't have to be of type IDisposable, it could be any type that implements it.
I've come across a post where Jon Skeet posted the following:
You can't use any parameterised constructor. You can use a
parameterless constructor if you have a "where T : new()" constraint.
I have the following method:
public T ReturnReader<T>(String filePath) where T : TextReader, new()
{
return new T(filePath);
}
which violates what he mentions above. I need the above method to be able to return both a StreamReader (production code) and a StringReader (unit testing purposes). As far as i can see, streamReader doesnt contain a parameterless constructor so i cant create a parameterless instance and then assign the filePath to it in the calling method.
Anyone see a solution to this?
Thanks for your time!
EDIT: original Methods, A and B
/// <summary>
/// Ensures number of columns stated == number of columns in file.
/// </summary>
/// <param name="errorMessageList">A running list of all errors encountered.</param>
public static void ValidateNumberOfColumns(string filePath, int userSpecifiedColumnCount, List<String> errorMessageList)
{
int numberOfColumnsInFile = GetNumberOfColumnsInFile(filePath, errorMessageList);
if (userSpecifiedColumnCount != numberOfColumnsInFile) errorMessageList.Add("Number of columns specified does not match number present in file.");
}
public static int GetNumberOfColumnsInFile(string filePath, List<String> errorMessageList)
{
int numberOfColumns = 0;
string lineElements = null;
try
{
using (StreamReader columnReader = new StreamReader(filePath))
{
lineElements = columnReader.ReadLine();
string[] columns = lineElements.Split(',');
numberOfColumns = columns.Length;
}
return numberOfColumns;
}
catch (Exception ex)
{
errorMessageList.Add(ex.Message);
return -1;
}
}
If you have to resort to reflection to make code feasible for unit testing, that's a bit of a smell - only an indication that you may want to reconsider the design, but certainly something to think about.
I would be tempted to abstract this into a separate interface - IPathReader or something similar:
public interface IPathReader
{
TextReader CreateReader(string path);
}
Then inject that into the class that you're testing - with an implementation using StringReader in testing, and an implementation using StreamReader in production. (I suspect you don't really need it to return different types.)
Note that this is effectively just a Func<string, TextReader> - so you could use that instead of an interface if you wanted.
Activator.CreateInstance it's not good idea because it's too expensive, so you could try this
StringReader reader = ReturnReader(() => new StringReader(filePath));
StreamReader streamReader = ReturnReader(() => new StreamReader(filePath));
private T ReturnReader<T>(Func<T> reader)
where T : TextReader
{
return reader();
}
EDIT
as per code, I think the best way is to separate NumberOfColumns and getting first row. So the new method NumberOfColumns will not depend from stream readers
You can easily accomplish this by using reflection:
public T ReturnReader<T>(String filePath) where T : TextReader
{
return (T)Activator.CreateInstance(typeof(T),filePath);
}
Usage:
var rdr = ReturnReader<StringReader>("c:\\test.txt");
var rdr2 = ReturnReader<StreamReader>("c:\\test.txt");
I have used binary serialization to save an F# record from a C# class. All works fine:
F#:
type GameState =
{
LevelStatus : LevelStatus
Grid : Variable<Option<Ball> [,]>
...
}
let game_state : GameState = aGameState()
C#:
public void OnSaveGame() {
using (var stream = File.Open("game_status.sav", FileMode.Create))
{
var binary_formatter = new BinaryFormatter();
binary_formatter.Serialize(stream, PuzzleBobble.game_state);
}
}
Now, I'm refactoring my F# module and I would like to have a mutable record to serialize:
let mutable game_state = aGameState()
game_state <- myGameState()
This way the file is created but when I try to deserialize it I get a null object.
I've changed nothing of my previous implementation, except the added mutable keyword.
My question is: is there anything wrong with serialization of a mutable F# record? Or serialization it self is right, and I have to look for a different error somewhere else in my code?
EDIT:
Even accessing the record through methods like suggested #Brian, it seems not to work.
Here's some more details. When I deserialize the previous saved object this way (that works without game_state declared mutable):
public void OnLoadGame() {
using (var stream = File.Open("game_status.sav", FileMode.Open))
{
var binary_formatter = new BinaryFormatter();
try
{
GameLogic.GameState state = binary_formatter.Deserialize(stream) as GameLogic.GameState;
GameLogic.load_game_state(state);
}
catch (ArgumentNullException e) {
Console.WriteLine(e.Message);
}
}
}
I get the following exception:
'System.ArgumentNullException' in FSharp.Core.dll
I have once seen some weird bug where module-scoped mutable variables in F# libraries were not properly initialized, is it possible you're hitting that?
If you change the code to define
let getGameState() = game_state
let setGameState(x) = game_state <- x
and then use the get/set functions, instead of referring to the mutable variable directly, does the problem go away? If so, this might be an exotic compiler bug that we know about.
Does Java have a using statement that can be used when opening a session in hibernate?
In C# it is something like:
using (var session = new Session())
{
}
So the object goes out of scope and closes automatically.
Java 7 introduced Automatic Resource Block Management which brings this feature to the Java platform. Prior versions of Java didn't have anything resembling using.
As an example, you can use any variable implementing java.lang.AutoCloseable in the following way:
try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
...
}
Java's java.io.Closeable interface, implemented by streams, automagically extends AutoCloseable, so you can already use streams in a try block the same way you would use them in a C# using block. This is equivalent to C#'s using.
As of version 5.0, Hibernate Sessions implement AutoCloseable and can be auto-closed in ARM blocks. In previous versions of Hibernate Session did not implement AutoCloseable. So you'll need to be on Hibernate >= 5.0 in order to use this feature.
Before Java 7, there was no such feature in Java (for Java 7 and up see Asaph's answer regarding ARM).
You needed to do it manually and it was a pain:
AwesomeClass hooray = null;
try {
hooray = new AwesomeClass();
// Great code
} finally {
if (hooray!=null) {
hooray.close();
}
}
And that's just the code when neither // Great code nor hooray.close() can throw any exceptions.
If you really only want to limit the scope of a variable, then a simple code block does the job:
{
AwesomeClass hooray = new AwesomeClass();
// Great code
}
But that's probably not what you meant.
Since Java 7 it does: http://blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec
The syntax for the code in the question would be:
try (Session session = new Session())
{
// do stuff
}
Note that Session needs to implement AutoClosable or one of its (many) sub-interfaces.
Technically:
DisposableObject d = null;
try {
d = new DisposableObject();
}
finally {
if (d != null) {
d.Dispose();
}
}
The closest java equivalent is
AwesomeClass hooray = new AwesomeClass();
try{
// Great code
} finally {
hooray.dispose(); // or .close(), etc.
}
As of now, no.
However there is a proposal of ARM for Java 7.
If you're interested in resource management, Project Lombok offers the #Cleanup annotation. Taken directly from their site:
You can use #Cleanup to ensure a given
resource is automatically cleaned up
before the code execution path exits
your current scope. You do this by
annotating any local variable
declaration with the #Cleanup
annotation like so:
#Cleanup InputStream in = new FileInputStream("some/file");
As a
result, at the end of the scope you're
in, in.close() is called. This call is
guaranteed to run by way of a
try/finally construct. Look at the
example below to see how this works.
If the type of object you'd like to
cleanup does not have a close()
method, but some other no-argument
method, you can specify the name of
this method like so:
#Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
By default, the cleanup method is presumed to be
close(). A cleanup method that takes
argument cannot be called via
#Cleanup.
Vanilla Java
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
With Lombok
import lombok.Cleanup;
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
#Cleanup InputStream in = new FileInputStream(args[0]);
#Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
No, Java has no using statement equivalent.
In java 8 you can use try. Please refer to following page. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Please see this List of Java Keywords.
The using keyword is unfortunately not part of the list.
And there is also no equivalence of the C# using keyword through any other keyword as for now in Java.
To imitate such "using" behaviour, you will have to use a try...catch...finally block, where you would dispose of the resources within finally.
ARM blocks, from project coin will be in Java 7. This is feature is intended to bring similar functionality to Java as the .Net using syntax.
To answer the question regarding limiting scope of a variable, instead of talking about automatically closing/disposing variables.
In Java you can define closed, anonymous scopes using curly brackets. It's extremely simple.
{
AwesomeClass hooray = new AwesomeClass()
// Great code
}
The variable hooray is only available in this scope, and not outside it.
This can be useful if you have repeating variables which are only temporary.
For example, each with index. Just like the item variable is closed over the for loop (i.e., is only available inside it), the index variable is closed over the anonymous scope.
// first loop
{
Integer index = -1;
for (Object item : things) {index += 1;
// ... item, index
}
}
// second loop
{
Integer index = -1;
for (Object item : stuff) {index += 1;
// ... item, index
}
}
I also use this sometimes if you don't have a for loop to provide variable scope, but you want to use generic variable names.
{
User user = new User();
user.setId(0);
user.setName("Andy Green");
user.setEmail("andygreen#gmail.com");
users.add(user);
}
{
User user = new User();
user.setId(1);
user.setName("Rachel Blue");
user.setEmail("rachelblue#gmail.com");
users.add(user);
}