I am outputting the value of a boolean in my ASP.NET MVC Framework view, and would like to have a lower case true or false, rather than the default of True or False.
I understand that I could just do this:
#this.Model.MyBool.ToString().ToLower()
Alternatively, I could create an extension method. But this defeats the purpose of:
#this.Model.MyBool
I have read the post Why does Boolean.ToString output "True" and not "true", but most of the answers are pretty old.
Are there any more modern ways to accomplish this?
If you only want this for one bool variable you should use #Mohamed 's method. Else you can create an extension method (as you already said yourself):
public static class Extensions
{
public static string ToLowerString(this bool _bool)
{
return _bool.ToString().ToLower();
}
}
Then to use it:
public static void Main()
{
bool testBoolean = true;
Console.WriteLine(testBoolean.ToLowerString());
}
Why don't you try the following
public string MyStringBool
{
get { return MyBool ? "true" : "false" ; }
}
You can also do this which feels syntactically cleaner than true.ToString().ToLower() (in my opinion):
Json.Encode(true);
However under the hood this has far more overhead than using the .ToString.ToLower() implementation.
Json.Encode(object value) has much more error handling as it needs to account for the possibility of more complex objects being passed as arguments.
I did a little benchmarking on this to see what the difference actually is, and on my toaster of a dev box:
var sw0 = Stopwatch.StartNew();
sw0.Stop();
var sw1 = Stopwatch.StartNew();
var t1 = System.Web.Helpers.Json.Encode(true);
var e1 = sw1.ElapsedMilliseconds; // returns 6-9
var sw2 = Stopwatch.StartNew();
var t2 = true.ToString().ToLower();
var e2 = sw2.ElapsedMilliseconds; // returns 0
So really the impact isn't huge for a one off.
Looks like Microsoft recommends the following (incase you need it for XML too):
public static class BoolExtensions
{
public static string ToLowerString(this bool _bool)
{
return _bool.ToString().ToLowerInvariant();
}
}
[ToString.()] returns the constants "True" or "False". Note that XML is case-sensitive, and that the XML specification recognizes "true" and "false" as the valid set of Boolean values. If the String object returned by the ToString(IFormatProvider) method is to be written to an XML file, its String.ToLowerInvariant method should be called first to convert it to lowercase.
Related
edit; Based on responses, I may have been unclear in my final goal. I've updated the last section.
Situation
I have a number of variables which I need to perform the same operation on. In this case, they are strings, and can at the point we reach this code have the value null, "", "Blank", or they could already have an assigned other value that I want to keep.
if (String.IsNullOrEmpty(MyVar1) || "Blank".Equals(MyVar1))
MyVar1 = null;
if(String.IsNullOrEmpty(MyVar2) || "Blank".Equals(MyVar2))
MyVar2 = null;
...
if(String.IsNullOrEmpty(MyVar10) || "Blank".Equals(MyVar10))
MyVar10 = null;
Being a programmer that wants to keep my code clean and this block drives me mad, I'm looking for a way to create a list of these variables, and perform this same if statement + null assignment on each.
For an example, here's what I'd like to do:
MyVar1 = "Blank";
DreamDataStructure varList = new DreamDataStructure() { MyVar1, MyVar2, ..., MyVar10 };
foreach(ref string MyVar in varList)
{
if(String.IsNullOrEmpty(MyVar) || "Blank".Equals(MyVar))
MyVar = null;
}
Console.WriteLine(MyVar1); //Should now be null
What Doesn't Work
1) Because my variables are strings, I can't do something like this.
var myListOfVariables = new[] { &MyVar1, &MyVar2, ..., &MyVar10 };
If I could, I'd be able to foreach over them as expected. Because string is a managed type though, it cannot be passed by reference like this.
2) Similarly, if I just made a List<string> of the variables, they would be passed by value and wouldn't help my case.
3) These variables can't be wrapped in an outer object type, as they need to be used as strings in a large number of places in a legacy application. Assume that it would be too large an effort to change how they're used in every location.
Question
Is there a way to iterate over string (or other managed type) variables in a pass-by-reference way that will allow me to put the entire operation inside of a loop and reduce the duplication of code that's happening here?
The goal here is that I can use the original variables later on in my code with the updated values. MyVar1, etc, are referenced later on already by legacy code which expects them to be null or have an actual value.
If I understand your question correctly, I don't think what you want to do is possible. Please see this question: Interesting "params of ref" feature, any workarounds?
The only thing I can suggest (which I know doesn't answer your question) is creating a method to avoid duplication of your conditional logic:
void Convert(ref string text)
{
if (string.IsNullOrEmpty(text) || "Blank".Equals(text))
{
text = null;
}
}
You could create a function instead of passing references, which would also be more readable.
string Validate(string inputString)
{
return string.IsNullOrEmpty(inputString) || "Blank".Equals(inputString) ? null : inputString;
}
<...>
MyVar1 = Validate(MyVar1);
Update:
Now I get what you're trying to do. You have a bunch of variables, and you want to perform some sort of bulk operation on them without changing anything else. Putting them in a class isn't an option.
In that case you're really stuck operating on them one at a time. There are ways to shorten it, but you're pretty much stuck with the repetition.
I'd
create a string SanitizeString(string input) function
type x = SanitizeString(x); once for each variable
copy and paste the variable names to replace x.
It's lame, but that's about all there is.
Perhaps this would be a better approach. It ensures that the values are always sanitized. Otherwise you can't easily tell whether the values have been sanitized or not:
public class MyValues
{
private string _value1;
private string _value2;
private string _value3;
public string Value1
{
get { return _value1; }
set { _value1 = Sanitize(value); }
}
// repeat for other values
private string Sanitize(string input) =>
string.IsNullOrEmpty(input) || string.Equals("Blank", input) ? null : input;
}
That's one option. Another is to sanitize the inputs earlier. But ideally we want to ensure that a given class is always in a valid state. We wouldn't want to have an instance of a class whether the values may or may not be valid. It's better to ensure that they are always valid.
ref doesn't really factor into it. We don't need to use it often, if ever. With a value type or string we can just return a new value from a function.
If we're passing a reference type and we want to make changes to it (like setting its properties, adding items to a list) then we're already passing a reference and we don't need to specify ref.
I'd try to write methods first without using ref and only use it if you need to. You probably never will because you'll succeed at whatever you're trying to do without using ref.
Your comment mentioned that this is a legacy app and it's preferable not to modify the existing class. That leaves one more option - reflection. Not my favorite, but when you say "legacy app" I feel your pain. In that case you could do this:
public static class StringSanitizer
{
private static Dictionary<Type, IEnumerable<PropertyInfo>> _stringProperties = new Dictionary<Type, IEnumerable<PropertyInfo>>();
public static void SanitizeStringProperties<T>(T input) where T : class
{
if (!_stringProperties.ContainsKey(typeof(T)))
{
_stringProperties.Add(typeof(T), GetStringProperties(typeof(T)));
}
foreach (var property in _stringProperties[typeof(T)])
{
property.SetValue(input, Sanitize((string)property.GetValue(input)));
}
}
private static string Sanitize(string input)
{
return string.IsNullOrEmpty(input) || string.Equals("Blank", input) ? null : input;
}
private static IEnumerable<PropertyInfo> GetStringProperties(Type type)
{
return type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(property => property.PropertyType == typeof(string) && property.CanRead && property.CanWrite);
}
}
This will take an object, find its string properties, and sanitize them. It will store the string properties in a dictionary by type so that once it has discovered the string properties for a given type it won't have to do it again.
StringSanitizer.SanitizeStringProperties(someObject);
you can simply use a string[] and get the changes back to the caller method like this.
public Main()
{
var myVar1 = "Blank";
var myVar2 = "";
string myVar3 = null;
var myVar4 = "";
string[] dreamDataStructure = new string[] { myVar1, myVar2, myVar3, myVar4 };
}
private void ProcessStrings(string[] list)
{
for(int i = 0; i < list.Length; i++)
{
if (String.IsNullOrEmpty(list[i]) || "Blank".Equals(list[i]))
list[i] = null;
}
}
I am writing a simple C#.NET application where I have an if condition where I am checking if a string variable value is a string or another string or another string or another one, etcetc.
Something like this:
if(protocollo == "2019/0002391" || protocollo == "2019/0002390" || protocollo == "2019/0001990" || ........)
This solution works but it is not so elegant. What could be a smarter way to implement the same behavior?
I agree with #JeroenMostert that it really depends on the context of the rest of your application. That said, using an array of strings and checking if your string is in there is a nice straightforward solution. There are certianily solutions that would scale better, take a look at HashSet.
string[] s = new string[] { "2019/0002391", "2019/0002390", "2019/0001990", ... };
if (s.Contains(protocollo)) {
// fill in here
}
You never said, so I'm making the assumption that the strings you're checking against is hard-coded and not something that changes often. To that end, you could create a string[] or HashSet<string> in a static class so it only initializes the one time, then expose a method for checking a second string against the valid ones.
void Main()
{
Console.WriteLine(Protocols.ValidProtocol("2019/0002391")); //True
Console.WriteLine(Protocols.ValidProtocol("2018/0000000")); //False
}
// Define other methods and classes here
public static class Protocols
{
public static bool ValidProtocol(string protocol)
{
return _validProtocols.Contains(protocol);
}
private static readonly HashSet<string> _validProtocols = new HashSet<string>
{
"2019/0002391",
"2019/0002390",
"2019/0001990"
//etc, etc...
};
}
A solution like this would probably not be ideal if the list of strings you need to check against changes often. You'd probably want to pull the list from an external source like a file or a database if you need to modify it often.
I had some code similar to your example in a static extension method. I didn't want to have to instantiate an array every time the method was called, but I wanted to improve the readability of the code.
I improved the code using the switch expression which was added in C# 8. Here is the what your example might look like if implemented with a switch expression. Depending on what your code does if the condition is true you may be able to improve on this, but this is the basics.
var isProtocolloMatch = protocollo switch
{
"2019/0002391" => true,
"2019/0002390" => true,
"2019/0001990" => true,
_ => false
};
if (isProtocolloMatch)
{
// do stuff
}
I have a c# winforms .net 4 application which receives a 156 character message I then pass this message unchanged to multiple function in turn.
My question is is it inefficient to keep passing the same value as a parameter or is there a more efficient way?
so currently I have :
string code = getTheCode();
\\decode first part
string result1 = getResult1(code);
string result2 = getResult2(code);
...
value of code never changes after its initial assignment.
The answer is no. It is not inefficient to keep passing the same string as a parameter. You are just passing a reference to the string, so it is very efficient.
You could create a class with a constructor requiring you to pass your string as argument and set it as a private property. Then you could retrieve data using methods which would use this private property to calculate results.
But this is only a matter of coding style you prefer, of course (and whether you will use these methods in one or more places). For me it's more readable AND you get to make sure that code variable won't change in that instance of ResultGetter class.
public class ResultGetter
{
private readonly string _code;
public ResultGetter(string code)
{
_code = code;
}
public string GetResult1()
{
var returnValue = // do something with _code property
return returnValue;
}
public string GetResult2()
{
var returnValue = // do something with _code property
return returnValue;
}
// et cetera ad nauseam
}
And then in your main file:
var code = getTheCode();
var rg = new ResultGetter(code);
string result1 = rg.GetResult1();
string result2 = rg.GetResult2();
It may be inefficient to keep passing the same code to several methods. If you find you have to do this many times, you might want to create a class responsible for 'getting results'. Pass the ''code' in the constructor of this new class. This way you can reuse the 'code' during the lifetime of the class and you don't have to keep passing the same value as a parameter
I'm working with a DNN form-building module that allows for some server-side code to be run based on a condition. For my particular scenario, I need my block of code to run if the first 4 characters of a certain form text are numeric.
The space to type the condition, though, is only one line and I believe gets injected into an if statement somewhere behind the scenes so I don't have the ability to write a mult-line conditional.
If I have a form field called MyField, I might create a simple conditional like this:
[MyField] == "some value"
Then somewhere behind the scenes it gets translated to something like if("some value" == "some value") {
I know that int.TryParse() can be used to determine whether or not a string is numeric but every implementation I've seen requires two lines of code, the first to declare a variable to contain the converted integer and the second to run the actual function.
Is there a way to check to see if the first 4 characters of a string are numeric in just one line that can exist inside an if statement?
Wrap it in an extension method.
public static class StringExtensions
{
public static bool IsNumeric(this string input)
{
int number;
return int.TryParse(input, out number);
}
}
And use it like
if("1234".IsNumeric())
{
// Do stuff..
}
UPDATE since question changed:
public static class StringExtensions
{
public static bool FirstFourAreNumeric(this string input)
{
int number;
if(string.IsNullOrEmpty(input) || input.Length < 4)
{
throw new Exception("Not 4 chars long");
}
return int.TryParse(input.Substring(4), out number);
}
}
And use it like
if("1234abc".FirstFourAreNumeric())
{
// Do stuff..
}
In response to this:
Is there a way to check to see if the first 4 characters of a string are numeric in just one line that can exist inside an if statement?
You guys don't have to make it account for anything more complicated than a positive integer.
new Regex(#"^\d{4}").IsMatch("3466") // true
new Regex(#"^\d{4}").IsMatch("6") // false
new Regex(#"^\d{4}").IsMatch("68ab") // false
new Regex(#"^\d{4}").IsMatch("1111abcdefg") // true
// in an if:
if (new Regex(#"^\d{4}").IsMatch("3466"))
{
// Do something
}
Old answer:
If you can't use TryParse, you could probably get away with using LINQ:
"12345".All(char.IsDigit); // true
"abcde".All(char.IsDigit); // false
"abc123".All(char.IsDigit); // false
If you can, here's an IsNumeric extension method, with usage:
public static class NumberExtensions
{
// <= C#6
public static bool IsNumeric(this string str)
{
float f;
return float.TryParse(str, out f);
}
// C# 7+
public static bool IsNumeric(this string str) => float.TryParse(str, out var _);
}
// ... elsewhere
"123".IsNumeric(); // true
"abc".IsNumeric(); // false, etc
"-1.7e5".IsNumeric(); // true
How about some easy LinQ?
if (str.Take(4).All(char.IsDigit) { ... }
I find myself often needing to use int.TryParse() to test if a value is an integer. However, when using TryParse, I have to pass a reference variable to the function. So I find myself always needing to create a temp int to be passed in. Usually it looks something like:
int my_temp_integer;
int.TryParse(potential_integer, my_temp_integer);
I find this to be quite cumbersome considering that all I want is a simple true/false response, and I don't care about the actual parsed result. Is there a better way to approach this? Why isn't there an overloaded function where I can just pass the value I want to test and get a true/false response?
Thanks.
you could write an extension method:
public static bool IsInt(this string pString)
{
int value;
return int.TryParse(pString, out value);
}
then your example becomes:
potential_integer.IsInt();
EDIT:
Lately I have been using a generic form of this.
public delegate bool TryParser<T>(string pString, out T pResult);
public static bool Is<T>(this string pString, TryParser<T> pTryParser)
{
T val;
return pTryParser(pString, out val);
}
Can then use it as follows; it's not perfect, but it's more concise than anything I've found:
"1234".Is<int>(int.TryParse); // true
"asdf123".Is<int>(int.TryParse); // false
"1.2345".Is<float>(float.TryParse); // true
"1000".Is<byte>(byte.TryParse); // false
Theoretically, this would also work with custom TryParse methods, as long as you followed the same pattern as the official ones.
Update: If you maintain a static dictionary of TryParse methods by type, you can avoid having to ever directly pass the method. The dictionary can even be populated as needed with reflection.
A simple solution is to create an extension method.
public static class StringExtensions {
public static bool IsInt(this string s) {
int i; return Int.TryParse(s, out i);
}
}
Then you just use it as so:
string s = "123";
if (s.IsInt())
// do something.
if you don't want to actually convert the string, only test it, then you can use Regex
something kinda like this (you may need to adjust this to fit your needs):
public bool IsInt(this string inputData)
{
Regex isNumber = new Regex(#"^\d+$");
Match m = isNumber.Match(inputData);
return m.Success;
}
You could use
bool isInt = str.TrimEnd( new char[] {'0','1','2','3','4','5','6','7','8','9'})
.Length == 0;
A shorter alternative to Muad'Dib above:
bool IsInt(string input)
{
return new System.Text.RegularExpressions.Regex(#"^\d$").IsMatch(input);
}
/Hans