Try-catch creating new array in C# - where to initialize it? - c#

If I'm reading a string from a config file, I'd use a similar approach to the below, in case the string isn't present in the file being read and an exception results. However, if I want to do the same for a string[] array, I can't just 'new it up' outside the try block because the size is not known.
I can't new it up in the try block itself. How should it be approached?
string[] logContent; // can't new it up here as don't know the size
try
{
logContent = File.ReadAllLines(aLogFile);
}
catch
{
throw new Exception("LoggerStandard: Specified Logfile exists but could not be read.");
}

You could initialize it to a default value:
string[] logContent = null;
try
{
logContent = File.ReadAllLines(aLogFile);
}
catch
{
// Be careful with the error message here => there might be other reasons
// that the ReadAllLines threw an exception
throw new Exception("LoggerStandard: Specified Logfile exists but could not be read.");
}

You can initialize it with null and then check against it.

By default it is null. You can leave it as is, if this is appropriate for your program, or initialize to any array according to your needs. Anyway, successful initialization inside of try block overrides this.

string[] logContent=null;
try
{
logContent = File.ReadAllLines(aLogFile);
}
catch
{
throw new Exception("LoggerStandard: Specified Logfile exists but could not be read.");
}

Related

How to make an object exist in the current context?

I fully understand why this is happening, but I don't know how to solve it as my attempts all didn't work.
I'm loading a file using MsgReader. I need to catch exceptions.
try
{
var message = MsgReader.Mime.Message.Load(fileInfo);
}
catch(IOException e)
{
MessageBox.Show(e.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
if (message.Attachments != null) //if has attachments
{
//...
This obviously fails as the object is created within the try. How can I instantiate the object but without having it load the file?
I've tried this before the try:
var message = new MsgReader.Mime.Message;
Error:
Severity Code Description Project File Line Suppression State
Error CS1526 A new expression requires an argument list or (), [], or {} after type
I've also tried variations of this, but I can't find the type I need to specify.
As the error states, if you want to create a new object then you need parentheses to invoke the constructor:
var message = new MsgReader.Mime.Message();
However, in this case it looks like you don't actually want a new instance, but just to declare the variable:
MsgReader.Mime.Message message = null;
In this case the declaration just needs an explicit type specified because var won't be able to infer the type from just null.
Just be aware that if the code in the try fails then message will be null and can't be used/dereferenced.
(And, of course, remove the var keyword when assigning a value to the variable within the try block.)

How can you capture the offending line from TextFieldParser when it throws an error?

I'm using the TextFieldParser class to read CSV files. It has two methods for ingesting lines of data: ReadFields() and ReadLine(). As you might imagine the former treats the data as columnar, separated by pre-set delimiters and the latter reads the raw data. I'm using the former, in code like this:
using (TextFieldParser parser = new TextFieldParser(newestFile.FullName))
{
parser.Delimiters = ","
parser.HasFieldsEnclosedInQuotes = true;
while (!parser.EndOfData)
{
try
{
List<string> result = parser.ReadFields().ToList();
// do something
}
catch(MalformedLineException ex)
{
// log error to record line where it happened
}
}
}
The catch for MalformedLineException is there to ensure the thing doesn't fall over if it meets a line that doesn't meet the parsing criteria - it might have additional quotes within a field, for example - it registers this and then moves on to the next line without bringing the whole thing to a halt.
What I'd really like to do in the catch block, though, is log the actual text of the line along with the line number to make it a bit easier to find out what the problem was. But I have no idea how I can get it: ReadFields appears to move on to the next line even when it errors, and if I call ReadLine in the catch block it also moves on to the next line, meaning lines get skipped. It does not appear to be part of the exception thrown, or available via the object when ReadFields fails.
Is there a way to use the TextFieldParser to capture this data?
I didn't actually intend to answer my own question, but this turned out to be very easy: there are other methods on the object to do just this: ErrorLine and ErrorLineNumber.
using (TextFieldParser parser = new TextFieldParser(newestFile.FullName))
{
parser.Delimiters = ","
parser.HasFieldsEnclosedInQuotes = true;
while (!parser.EndOfData)
{
try
{
List<string> result = parser.ReadFields().ToList();
// do something
}
catch(MalformedLineException ex)
{
int errorLine = parser.ErrorLineNumber;
string originalData = parser.ErrorLine;
// log them
}
}
}

Visual Studio Code Analysis - CA1804 thrown when variable is being used

I'm using VS2015 on Windows 7.
Code analysis rule CA1804 (http://msdn.microsoft.com/library/ms182278.aspx) states that I am not using a variable and to remove it. However, I am using this variable further down in my code. This is happening across the whole solution in hundreds of places. The code block looks like this:
[WebMethod]
public bool ValidateUser(string userName, string password)
{
string soapResult = String.Empty;
try
{
// code here
using (StreamReader rd = new StreamReader(responseStream))
{
soapResult = rd.ReadToEnd();
}
// code here
bool isValidated = true;
}
catch (Exception e)
{
// throw error
}
return isValidated;
}
I'm getting this error from Code Analysis:
Error CA1804 'ValidateUser(string, string)' declares a variable, 'soapResult', of type 'string', which is never used or is only assigned to. Use this variable or remove it.
Is there something I'm missing here? It's not within an if/else like some of the instances I'm getting this error. But I figured that if it's being used at all this error would not be thrown.
Thanks for any help.
Read the analysis message carefully, note the bit I have highlighted:
Error CA1804 'ValidateUser(string, string)' declares a variable, 'soapResult', of type 'string', which is never used or is only assigned to. Use this variable or remove it.
It is telling you that you only assign a value to it (you actually do that twice including the initialisation to string.Empty) but you never use the value. So it's effectively a waste of a variable.
What you should be doing is either using the value, for example:
soapResult = rd.ReadToEnd();
if(soapResult.Contains("something")
{
isValidated = true;
}
else
{
//Not needed but added it to better show how this works in context
isValidated = false;
}
Or remove it altogether and discard the result you get from the StreamReader:
rd.ReadToEnd();

Initialization of C# String array

I want to declare a string array, I was using this way of doing it
string[] matchingFiles = Directory.GetFiles(FilePath, FileNamePattern);
which worked perfectly, but now I want to enclose the Directory.GetFiles call in a try/catch block, but I cant also have the declaration of the string array in there because then it wont be in the right scope to use it outside of the try block. But if I try this:
string[] matchingActiveLogFiles;
try
{
matchingFiles = Directory.GetFiles(FilePath, FileNamePattern);
}
catch (Exception ex)
{
//logerror
}
I have not initialized the string array so I have an error. So I am wondering what is best practise in this situation, should I declare the string array outside the try block? And if so how?
The name is different for the string arrays, one is matchingActiveLogFiles the other is
matchingFiles
string[] matchingActiveLogFiles;
try
{
matchingActiveLogFiles = Directory.GetFiles(FilePath, FileNamePattern);
}
catch (Exception ex)
{
//logerror
}
This will initialize your array:
string[] matchingActiveLogFiles = {};
try
{
matchingFiles = Directory.GetFiles(FilePath, FileNamePattern);
}
catch (Exception ex)
{
//logerror
}
But I'm wondering, what error are you getting? Even with an uninitialized array, the above code should work. I also noticed that you have "matchingActiveLogFiles" on line 1 and "matchingFiles" on line 4. Perhaps that's your problem?
Initialize it first:
string[] matchingActiveLogFiles = new string[0];
The issue is your naming. You're defining matchingActiveLogFiles but assigning matchingFiles.
You should declare the variable in the scope in which that variable is needed.
If you only need the variable in the try block, put it in there!
If you need it outside of the try block, what do you want the value to be if your code can't get the file contents? Set it to that on error.
Though I generally dislike methods with out params, this seems like a good candidate for a Try method:
bool TryGetMatchingLogFiles(out string[] matchingFiles )
{
matchingFiles = null;
try
{
matchingFiles = Directory.GetFiles(FilePath, FileNamePattern);
return true;
}
catch (Exception ex)
{
//logerror
return false;
}
}
Usage:
string[] matchingActiveLogFiles;
if (TryGetMatchingLogFiles(out matchingActiveLogFiles))
{
// Use matchingActiveLogFiles here
}
Or alternatively, just initialise your variable to null:
string[] matchingActiveLogFiles = null;
try ...
you do not have to know the exact number of Items in order to initialize an array like
string[] matchingActiveLogFiles = {};
this is what is called a dynamic array it's totally functional and I've had ZERO issues with declaring arrays this way..
List<string> matchingFiles= new List<string>();
try
{
matchingFiles.Add(Directory.GetFiles(FilePath, FileNamePattern));
matchingActiveLogFiles = matchingFiles.ToArray();
}
catch (Exception ex)
{
//logerror
}

RichTextBox lifetime in static method context

Please take a look at the method depicted below
public static string RemoveRTF(string input)
{
string output = input;
RichTextBox RichTextBox1 = new RichTextBox();
try {
RichTextBox1.Rtf = input;
output = RichTextBox1.Text;
} catch (ArgumentException argExp) {
/*
* The supplied input value is not in RTF format.
* Ignore.
*/
}
return output;
}
My question is, will the above code when called several times generate a large amount of USER Objects, Handles Or GDI Objects.
The reason for asking is that I have some code which worked perfectly one day and then the next day without any code changes made stopped working with the reported error :
Error creating Window Handle..
Only thing is that I cant seem to see the cause for the problem except that the callstack shows me that the error originates in the above code.
TaskManager do not reveal a large amount of USER objects or such being created, so I really do not know what is going on.
You should dispose your RichTextBox to free up any unmanaged resources.
RichTextBox1.Dispose();
or you can make one global RichTextBox and use it.
RichTextBox RichTextBox1 = new RichTextBox();
public static string RemoveRTF(string input)
{
string output = input;
try {
RichTextBox1.Rtf = input;
output = RichTextBox1.Text;
RichTextBox1.rtf = null;
} catch (ArgumentException argExp) {
/*
* The supplied input value is not in RTF format.
* Ignore.
*/
}
return output;
}
or use using()
The RichTextBox object only works on the UI thread. Calling this code from the background thread will throw an Exception with a message like "Error creating Window Handle.."
I also received the same error that u r facing "Error creating window handle". This issue occurs because even if we create object of RichTextBox and and set that object to null at the end of the method, it does not get disposed and so initially it works fine and then later on it start giving "error creating window handle". So instead use "Using". It will dispose object of richTextBox outside "using" context. This will solve that error.
private String RemoveRtf(String RtfScript)
{
string PlainText = null;
try
{
if (!String.IsNullOrEmpty(RtfScript))
{
using (RichTextBox richTxtBox = new RichTextBox())
{
richTxtBox.Rtf = RtfScript;
PlainText = richTxtBox.Text;
}
}
}
catch (Exception ex)
{
// log error here
}
finally
{
RtfScript = null;
}
return PlainText;
}

Categories

Resources