C# If Contains? - c#

I am new to C# and I'm trying to write a contains statement. I want the process to read the test variable and if it contains the word error then print the variable if it does not contain an error then print no error. I think my process is close except when I run the code below I get an error when the CLI runs.
"object reference not set to an instance of an object"
Any help would be appreciated!
while (true)
{
test = queue.GetMessage();
if (test.AsString.Contains("error"))
{
Console.WriteLine(string.Format("Variable: {0}", test.AsString));
}
else
Console.WriteLine(string.Format("No Error: {0}", test.AsString));
}

var message = queue.GetMessage()?? string.Empty;
var formattedMessage =
String.Format(
(message.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0)
? "No Error: {0}"
: "Variable: {0}", message);
Console.WriteLine(formattedMessage);
Useful references:
Unique ways to use the Null Coalescing operator
Simplify conditional string format

If queue.GetMessage() return a string, then you don't need AsString. If you want to convert it to a string, override ToString().
while (true) {
test = queue.GetMessage();
if (test.ToString().Contains("error")) {
...
} else {
...
}
}
You can always guarantee that ToString() will be present because it's defined in the object base class. Just be sure it returns something intelligible, because default implementations may not.

Related

C#: Unassigned local variable with succeeded property pattern match

I have the following code using pattern matching with a property pattern that always succeeds:
var result = new { Message = "Hello!" } is { Message: string message };
Console.WriteLine(message);
The above match succeeds(result is true). However, when I try to print message, I get a:
CS0165: Use of unassigned local variable.
However, the following works:
var result = "Hello!" is { Length: int len };
Console.WriteLine(len);
Also, when I use it with an if, it just works fine:
if (new { Message = "Hello!"} is { Message: string message })
{
Console.WriteLine(message);
}
Why the discrepancies?
Why the discrepancies?
Well, it's a compile-time error, and at compile-time, it doesn't know that it would match. As far as the compiler is concerned, it's absolutely valid for result to be false, and message to be unassigned - therefore it's a compile-time error to try to use it.
In your second example, the compiler knows that it will always match because every string has a length, and in the third example you're only trying to use the pattern variable if it's matched.
The only oddity/discrepancy here is that the compiler doesn't know that new { Message = "Hello!" } will always match { Message: string message }. I can understand that, in that Message could be null for the same anonymous type... slightly more oddly, it looks like it doesn't know that it will always match { Message: var message } either (which should match any non-null reference to an instance of the anonymous type, even if Message is null).
I suspect that for your string example, the compiler is "more aware" that a string literal can't be null, therefore the pattern really, really will always match - whereas for some reason it doesn't do that for the anonymous type.
I note that if you extract the string literal to a separate variable, the compiler doesn't know it will always match:
string text = "hello";
var result = text is { Length: int length };
// Use of unassigned local variable
Console.WriteLine(length);
I suspect this is because a string literal is a constant expression, and that the compiler effectively has more confidence about what it can predict for constant expressions.
I agree that it does look a bit odd, but I'd be surprised if this actually affected much real code - because you don't tend to pattern match against string literals, and I'd say it's the string literal match that is the unexpected part here.

Conditional Null Operator invalid type in given context

Working with a Legacy Application, ASP.Net, c#.
Trying to append my log4net messages with the SessionWrapper.UserDisplayName
The hiccup is if the sessionwrapper is not defined, i don't want it to bomb, i just want it to treat it as null or empty and I'm trying to avoid writing a multiple lines of code.
Using this as the base for my idea:
banana = null;
string result2 = banana?.prop1 + "something new";
result 2 = something new
Applying that concept to my code:
SessionWrapper?.UserDisplayName + "error message"
I get an error compiling saying:
"SessionWrapper is a type and invalid int the current context"
Any insight is greatly appreciated -
A type is not a value and is therefore never null. If UserDisplayName is a static property of this type, then it might be null; however, it is okay to concatenate null with a string. null will be treated like an empty string.
Simply write
string result = SessionWrapper.UserDisplayName + "error message";
In banana?.prop1 the null-condition-operator is only useful if banana is null. The expression is equivalent to banana == null ? (string)null : banana.prop1.
If you want to treat the case where prop1 could be null, then use the null-coalescing operator ??.
string result2 = (banana.prop1 ?? "<empty>") + "something new";
Of course you can combine the two.
string result2 = (banana?.prop1 ?? "<empty>") + "something new";
Now, both, banana and prop1 can be null. In both cases you will get the result "<empty>something new".

C# Ignore error/warning on Substring

I use Substring to decode a generated code for activating
but when a user enter wrong code like 1 or 123
c# stop and say "Index and length must refer to a location within the string." or ..
how to ignore it without check length ...
in php we can ignore warnings and error by using "#"
#myfunc(12);
but how in C# ?
The short answer is, you can't.
The correct answer is you shouldn't, and to check that the input is valid.
The horrible answer would look something like this:
public void SwallowExceptions(Action action)
{
try
{
action();
}
catch
{
}
}
public string DoSomething()
{
string data = "TerribleIdea";
string result = null;
SwallowExceptions(() => result = data.Substring(0, 10000));
return result;
}

Empty String to Double using (Try)Parse

I've got a with 1.1 build system here using Parse for converting values (now it's 3.5).
string myString = String.Empty;
double myValue = double.Parse(myString);
throws a FormatException (I expected 0.0).
If I rewrite that using 2.0+
string myString = String.Empty;
double myValue;
if (double.TryParse(myString, out myValue))
//do something
I get the wanted 0.0, but unfortunately I lose the possibility to get a meaningful error message (in the else tree).
Why is giving me Parse an error and TryParse my expected value?
Is there any way to get the error message out of TryParse (time is not the problem)?
I don't want to work around it like that:
Avoid the error using if...then
myValue = myString.Length == 0 ? 0.0 : double.Parse(myString);
Two Calls if an error occured
if (!double.TryParse(myString, out myValue))
myValue = double.Parse(myString);
Parse throws an exception if the string cannot be be parsed and TryParse returns a bool. You can handle this bool (true if the parsing was successful, else false) to display the success/error message you want to show.
Since myValue is an out parameter it has to be set by the method so, if the string cannot be parsed, TryParse sets it as 0.0 which is why you're getting that number when using the TryParse method.
No, it is not possible to get the exact error message. You only want to know if it is possible to convert to double and the result, if it is possible. The exact reason why the conversion fails is hidden from you.
TryParse allows you to convert without throwing exception and returns true if successful. The action you take depends on you
if (!double.TryParse(myString, out myValue))
{
//throw exception here
}
It is useful when you are not sure if input will always be numbers
Why is giving me Parse an error and TryParse my expected value?
Because that's the way the interface is designed. TryParse does not throw an exception if the input has an invalid format. Instead it returns false.
Is there any way to get the error message out of TryParse (time is not the problem)?
No, but you can make your own error message.
if (double.TryParse(myString, out myValue))
{
//do something
}
else
{
throw new FooException("Problem!");
}
But if you want to throw an exception when there is an error it's simpler to just use Parse.
TryParse is implemented somehow like this:
try
{
Parse(...);
return true;
}
catch
{
return false;
}
So you can do it just the same way:
try
{
double.Parse(str, out dbl);
}
catch (Exception ex)
{
// Do something with ex.Message
dbl = 0.0;
}
// Continue with dbl.
Forget double.TryParse, as it won't tell you (by design) why the parsing failed. Do it The Old Way:
string myString = String.Empty;
double myValue = 0.0;
try
{
myValue = double.Parse(myString);
}
catch (FormatException)
{
// Now you have a meaningful story here!
}
Out parameters has to be set, therefore if TryParse fails it will initialize the output to it's default before it returns, however you will and in the "else" loop... Meaning it failed...
Try running the code below, that will show you that TryParse actually overwrites the value, yet indicates that the parse fails...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ParseAndOutput("");
ParseAndOutput("1.0");
ParseAndOutput("ABC");
}
private static void ParseAndOutput(string input)
{
double value = -1;
if (double.TryParse(input, out value))
{
Console.WriteLine("Parse succeeded for '"+input+"', try parse changed to: " + value);
}
else
{
Console.WriteLine("Parse failed for '" + input + "', try parse changed to: " + value);
}
}
}
}
So both Parse and TryParse fails on string.Empty, they just report that failure differently which is the whole point of TryParse, it is never meant to throw an exception...

IF condition with a string

Just a quick one:
string firstline;
if (firstline == null) {
System.Console.WriteLine("String empty!");
}
In theory if there is no value in "firstline", the console should out put "String empty!"?
This doesn't even compile because of:
Use of unassigned local variable 'firstline'
When you say you don't get any output but the program compiles and runs just fine, you are not showing us your real code.
However, if firstline is not a local variable but a member variable of the surrounding class, it will be automatically initialized with null. In general, all member variables of a class are initialized with default(T) where T is the type of the member variable.
You can't compile in VS with error: Use of unassigned local variable 'firstline' !
Try assign null before!
EDIT
or
class Program
{
static string firstline; # with static you can compile and got your behaviour
static void Main(string[] args)
{
if (firstline == null)
{
System.Console.WriteLine("String empty!");
}
Console.ReadKey();
}
}
In default they are not null. If you want it null by default use this:
static string firstline;
static void Main(string[] args)
{
if (firstline == null)
{
System.Console.WriteLine("String empty!");
}
}
But I suggest using this one:
static void Main(string[] args)
{
string firstline = null;
// or this:
//string firstline = String.Empty;
if (String.IsNullOrEmpty(firstline))
{
System.Console.WriteLine("String empty!");
}
}
In both ways you can get riddle of
Use of unassigned local variable 'firstline'
Yes that will behave as you expect and should print out to the console. You might find that the console application closes too quickly for you to read the result though if you've not got any following code.
Also null and "" (or String.Empty) often mean the same thing, so a more command way to do this is:
if(String.IsNullOrEmpty(firstline))
{
Console.WriteLine("String is empty!");
}
Your terminology makes it sound like you are a little confused.
A null string is precisely that - the absence of the value. It is not an empty string, it is a string with no value.
An empty string is a zero length string, "" or string.Empty. This is not null as it does have a value, but the value is zero length.
Often you want to treat the null and empty values the same, in which case you might use the check
if (string.IsNullOrEmpty(firstline))
{
System.Console.WriteLine("String is null or empty!");
}
Your code is not correct, Use of unassigned local variable 'firstline'. You can assign it with any value to test. If you want to check if it is an empty string, a better way is:
string firstline = null; //change to "" to test
if (string.IsNullOrEmpty(firstline))
{
System.Console.WriteLine("String empty!");
}
here are my 2 cents:
if (firstline == (string)null) throw new ArgumentNullException("firstline"); //value is null
if (firstline.Length == 0) throw new ArgumentOutOfRangeException("firstline", "Value is empty"); // string.Empty
I found this by using Pex and Moles

Categories