What is the C# equivalent of:
Public stringValue As String
Public intValue As Integer
intValue = Format(val(stringValue), "00")
?
So the vb6 Format function converts to string and the Val function converts to a number. If you look at the Microsoft documentation for Val:
Val(" 1615 198th Street N.E.")
// returns
1615198
in c# this can clumsily be converted to
string stringValue = " 1615 198th Street N.E.";
// assign to int if int wanted
// throws exception if cannot be converted to int, use Int32.TryParse if you want to handle that
int intValue = System.Convert.ToInt32(
new string(stringValue.Replace(" ", "").TakeWhile(System.Char.IsDigit).ToArray())
);
System.Console.WriteLine(intValue);
it's really going to depend on what your expectations are for what stringValue is going to be and what you want returned. Also I don't think you can assign a string value to an int so willy nilly like you can in vb6. It can definitely be cleaned up but that just depends on what you're doing.
edit:
Since you're testing a stringValue = "3" this should work
string stringVal = "3";
if(!System.Int32.TryParse(stringVal, out int intValue))
{
System.Console.WriteLine($"value={stringVal} not of type int");
}
return intValue;
If truly replicating the VB6 Val function is desired, then Microsoft.VisualBasic.Val can be used. It is pretty faithful to the original, and of course can be called from C#.
See https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.conversion.val?view=netcore-3.1#Microsoft_VisualBasic_Conversion_Val_System_String_ for the string overload (returns Double).
One aspect where it doesn't return the same result as VB6 is for a string like "3.4.5". VB6 Val will return 34.5, while the .Net Val will return 3.4.
No need for exception handling (just like with VB6), if the input can't be converted to a number, no exception is thrown (well, mostly, there are some edge cases) or error returned, the return value is zero.
Related
I want to convert string to int but some time is not working.
Here is my code:
public static int ToInt(String pStr)
{
return Convert.ToInt32(Microsoft.VisualBasic.Conversion.Val(pStr));
}
Int i = ToInt("F0005");
Output is 0 - it works fine.
But when I pass in a value like this
Int i = ToInt("E0305");
Then I get an error "Out-of-range exception".
I have a mix of values, some are int and some are strings; I want to pass each and every value in loop and convert it to int, but when I pass this value then I get an error.
If you just want to skip invalid string value, it is better to use TryParse instead of returning 0 (which might be valid value). At your calling code it should look like this:
string val = "F0005";
if (int.TryParse(val, out int i) {
// parse success. you can use i here
}
else {
// parse failed.
}
If you really want it to be 0, this should work
string val = "F0005";
int i = int.TryParse(val, out int x) ? x : 0;
You can do it in C# alone without VB.NET library
public static int ToInt(string pStr)
{
return int.Parse(pstr);
}
Noted that this will throw exception if pStr is not a valid integer string. In your case, it might also throw exception if the value is too big, which you might need long instead to hold bigger numbers.
public static long ToInt64(string pStr)
{
return long.Parse(pstr);
}
Also, I just noticed that you are trying to parse "E0305" which is not really a valid format (as far as I know). The closest one is "1E305", which means 1 with 305 zeroes afterward. If you need to parse an integer that big, you might need BigInteger
public static BigInteger ToBigInteger(string pStr)
{
return BigInteger.Parse(pstr, System.Globalization.NumberStyles.AllowExponent);
}
The System.Globalization.NumberStyles.AllowExponent part is there to allow parsing the number in exponent representation.
Try using int.TryParse() method for those cases where you have some unexpected and you do not want exceptions in proces of parsing them.
Use case for it would be:
var isValid = int.TryParse(pStr, out int result);
Also another benefit of using it is that you have return value that provides you a way to handle unsuccessful parsing call.
In my code i try to get browser version for charging the good css file, but this code doesn't work, and i don't see my error...
I've simply try first with a Convert.ToInt32 but don't works too...
public ActionResult Index()
{
ViewBag.logged = false;
ViewBag.BrowserName = Request.Browser.Browser.ToString();
Int32 v = 0;
string version = Request.Browser.Version;
if (version != null)
{
bool result = Int32.TryParse(version, out v);
}
ViewBag.BrowserVersion = v;
return View();
}
In my debugger :
version => string : "23.0"
v => int 0
result => false
Request.Browser.Version => string "23.0"
This is by design.
Parsing a version string would work better with System.Version.
You can, alternatively, parse it to a float and then see if a lossless conversion to Int32 can be made.
I fully agree with Andrei's answer; that's the approach you should take.
However, I think it's important to note that there is a way to parse int values from strings such as "23.0": it can be done using this overload of int.TryParse() which allows you to pass NumberStyles flags as parameters.
Concretely, after executing this code:
int v;
var wasParsedOK = Int32.TryParse(
"23.0",
NumberStyles.AllowDecimalPoint,
CultureInfo.InvariantCulture,
out v);
v will hold the value 23 and wasParsedOK will be true.
You can't assume that the version string is going to be integral, or even decimal. A browser could perfectly report 7.0b as its version. None of int, float, decimal or System.Version can represent this.
If you're only concerned about the major and minor version numbers, you can use the MajorVersion and MinorVersion properties of your Browser object, assuming it is of type HttpBrowserCapabilities. The framework has done the parsing for you, so it should be reliable.
It is giving false because 23.0 is not an int, So you can try with decimal,double or float.
decimal v = 0;
string version = "23.0";
Decimal.TryParse(version, out v);
It's been almost 2 years and no one has answered this correctly. The question is simple, "Why is it returning false?"
This question has already been answered, simply because your string is not an Integer, but is a Double or Decimal. By design, TryParse will try to get the EXACT match of the type integer from your string, if not it will return false, and your string ("23.0") is not an exact match.
Now if you're trying to find a solution in converting your version string to a number, What you can do is filter out the non-numeric, excluding 1 dot (.), in the string, then convert what's left to decimal/double. After this conversion you can then try converting it integer. Since you already converted your stirng to double/decimal, you can no longer use TryParse because the parameter needs to be in string format. You can then use Convert.ToInt32 inside a Try block.
Sometimes i wonder, when converting strings to other types, for example int32, is one way better than the other, or is it just a matter of taste?
Convert.ToInt32("123")
or
Int32.Parse("123")
or
Some other way?
Not considering the case if it's not a valid int in this question.
The Convert.ToInt32 is actually implemented the following way...
int.Parse(value, CultureInfo.CurrentCulture);
...which is the same as your stated alternative except it takes into account the culture settings. The int.Parse method is itself implemented the following way...
Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
...where Number is an internal class that you cannot call directly. The Number.ParseInt32 method is marked with the following attribute...
[MethodImpl(MethodImplOptions.InternalCall)]
...showing that it is implemented inside the CLR itself.
Main difference between Conver.ToInt32 and Int32.Parse is how the treat null strings. Convert.ToInt32 returns default value in this case:
public static int ToInt32(string value)
{
if (value == null)
return 0;
return Int32.Parse(value, CultureInfo.CurrentCulture);
}
I don't like that. I think only "0" should be parsed to 0. This behavior initially was designed for Visual Basic programmers:
This is a set of conversion methods for programmers migrating from Visual Basic 6 to Visual Basic .NET that mirrored the behavior of the
existing Visual Basic 6 conversion methods. The assumption was that C#
programmers would be more comfortable with casting operators, whereas
Visual Basic had traditionally used conversion methods for type
conversion.
So, as non-VB programmer, I'd go with Int32.Parse and Int32.TryParse.
When converting from string to int I always use int.TryParse. Because you are not always sure you can convert a string to an int. Like this:
string temp="222";
int intValue;
if(int.TryParse(temp,out intValue))
{
//Something
}
As V4Vendetta suggested it is better to use TryParse to avoid exceptions related to converting.
int result = 0;
a = "3";
string b = "b";
string c = "2147483648"; //int32 max value + 1
int.TryParse(a, out result); // returns true result=3
int.TryParse(b, out result); // returns false result=0
int.TryParse(c, out result); // returns false result=0
This is probably trivial, but I can't think of a better way to do it. I have a COM object that returns a variant which becomes an object in C#. The only way I can get this into an int is
int test = int.Parse(string.Format("{0}", myobject))
Is there a cleaner way to do this? Thanks
You have several options:
(int) — Cast operator. Works if the object already is an integer at some level in the inheritance hierarchy or if there is an implicit conversion defined.
int.Parse()/int.TryParse() — For converting from a string of unknown format.
int.ParseExact()/int.TryParseExact() — For converting from a string in a specific format
Convert.ToInt32() — For converting an object of unknown type. It will use an explicit and implicit conversion or IConvertible implementation if any are defined.
as int? — Note the "?". The as operator is only for reference types, and so I used "?" to signify a Nullable<int>. The "as" operator works like Convert.To____(), but think TryParse() rather than Parse(): it returns null rather than throwing an exception if the conversion fails.
Of these, I would prefer (int) if the object really is just a boxed integer. Otherwise use Convert.ToInt32() in this case.
Note that this is a very general answer: I want to throw some attention to Darren Clark's response because I think it does a good job addressing the specifics here, but came in late and wasn't voted as well yet. He gets my vote for "accepted answer", anyway, for also recommending (int), for pointing out that if it fails (int)(short) might work instead, and for recommending you check your debugger to find out the actual runtime type.
The cast (int) myobject should just work.
If that gives you an invalid cast exception then it is probably because the variant type isn't VT_I4. My bet is that a variant with VT_I4 is converted into a boxed int, VT_I2 into a boxed short, etc.
When doing a cast on a boxed value type it is only valid to cast it to the type boxed.
Foe example, if the returned variant is actually a VT_I2 then (int) (short) myObject should work.
Easiest way to find out is to inspect the returned object and take a look at its type in the debugger. Also make sure that in the interop assembly you have the return value marked with MarshalAs(UnmanagedType.Struct)
Convert.ToInt32(myobject);
This will handle the case where myobject is null and return 0, instead of throwing an exception.
Use Int32.TryParse as follows.
int test;
bool result = Int32.TryParse(value, out test);
if (result)
{
Console.WriteLine("Sucess");
}
else
{
if (value == null) value = "";
Console.WriteLine("Failure");
}
Maybe Convert.ToInt32.
Watch out for exception, in both cases.
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
I am listing the difference in each of the casting ways. What a particular type of casting handles and it doesn't?
// object to int
// does not handle null
// does not handle NAN ("102art54")
// convert value to integar
int intObj = (int)obj;
// handles only null or number
int? nullableIntObj = (int?)obj; // null
Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null
// best way for casting from object to nullable int
// handles null
// handles other datatypes gives null("sadfsdf") // result null
int? nullableIntObj2 = obj as int?;
// string to int
// does not handle null( throws exception)
// does not string NAN ("102art54") (throws exception)
// converts string to int ("26236")
// accepts string value
int iVal3 = int.Parse("10120"); // throws exception value cannot be null;
// handles null converts null to 0
// does not handle NAN ("102art54") (throws exception)
// converts obj to int ("26236")
int val4 = Convert.ToInt32("10120");
// handle null converts null to 0
// handle NAN ("101art54") converts null to 0
// convert string to int ("26236")
int number;
bool result = int.TryParse(value, out number);
if (result)
{
// converted value
}
else
{
// number o/p = 0
}
There's also TryParse.
From MSDN:
private static void TryToParse(string value)
{
int number;
bool result = Int32.TryParse(value, out number);
if (result)
{
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}
else
{
if (value == null) value = "";
Console.WriteLine("Attempted conversion of '{0}' failed.", value);
}
}
Strange, but the accepted answer seems wrong about the cast and the Convert in the mean that from my tests and reading the documentation too it should not take into account implicit or explicit operators.
So, if I have a variable of type object and the "boxed" class has some implicit operators defined they won't work.
Instead another simple way, but really performance costing is to cast before in dynamic.
(int)(dynamic)myObject.
You can try it in the Interactive window of VS.
public class Test
{
public static implicit operator int(Test v)
{
return 12;
}
}
(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass
You can first cast object to string and then cast the string to int;
for example:
string str_myobject = myobject.ToString();
int int_myobject = int.Parse(str_myobject);
this worked for me.
int i = myObject.myField.CastTo<int>();
This worked for me, returning 0 also when myobject contains a DBNull
int i = myobject.ToString().Cast<int>().FirstOrDefault();
I have the following variables:
string str1 = "1";
string str2 = "asd";
string str3 = "3.5";
string str4 = "a";
Now I need to find the data type of each string i.e. the data type to which it can be converted if quotes are removed. Here is what I would like each variable to convert to:
str1 - integer
str2 - string
str3 - double
str4 - char
Note: if the string has single character it should be char, though a string can have single letter, I'm limiting it.
FYI: these values are obtained from DataGrid where i manually entered values. So everything is becoming a string.
Is there any way to do this?
Of course, there's no definite way to do this, but if you create a list of data types you want to check ordered by priority, then something like this may do the trick.
object ParseString(string str)
{
int intValue;
double doubleValue;
char charValue;
bool boolValue;
// Place checks higher if if-else statement to give higher priority to type.
if (int.TryParse(str, out intValue))
return intValue;
else if (double.TryParse(str, out doubleValue))
return doubleValue;
else if (char.TryParse(str, out charValue))
return charValue;
else if (bool.TryParse(str, out boolValue))
return boolValue;
return null;
}
Just call this function on each string, and you should have the appropiate type of object returned. A simple type check can then tell you how the string was parsed.
Use meta-data, if you can
That you have to guess what the data types are, is not a good idea.
Two things
1 Where is the data coming from?
If it's a database, are you sure they're strings?
If it is a database, there should be some meta data returned that will tell you what the datatypes of the fields are.
If it's an Xml file, is there a schema defined that will give you the types?
2 If you have to continue to guess.
Be aware that you can have strings that happen to be numbers, but are perfectly valid strings e.g phone numbers, bank acount numbers, that are best expressed as strings.
Also these numbers can have many digits, if you convert them to doubles you may loose some digits to floating point inaccuracies (you should be OK up to 14 or 15 digits)
I'm sure by now - cause I've taken my time typing this - there are lots of answers telling you how to do this (i.e. tryparse int first, then double, then test length for char, if not then it's a string etc), but if I were you, I'd try to NOT do that, and see if there's any way you can get, or pass some meta-data that will tell you what type it IS and not just what type it might be
Use the TryParse method of each type.
There is no built in way to do this, you could attempt TryParse on number types with increasing precision, but it wouldn't guarantee it to be right.
Your best bet what be to process it like you would manually. i.e. Is there a decimal place? No - then its an integer. How big? Is it negative?
The datatype for each of these items is string. If you want to attempt to parse them into different types you can use Int32.TryParse, Double.TryParse, etc. Or you can use Regex:
bool isInt = new Regex(#"^\d+$").IsMatch(str);
bool isDouble = !(isInt) && new Regex(#"^\d+\.\d+$").IsMatch(str);
bool isChar = !(isInt || isDouble) && new Regex(#"^.$").IsMatch(str);
bool isString = !(isInt || isDouble || isChar);