Converting VB6 Optional Parameter to C# [duplicate] - c#

This question already has answers here:
How can you use optional parameters in C#?
(23 answers)
Closed 8 years ago.
I have a VB6 function that has an optional date interval parameter that I'm trying to convert to C#. I'm also not sure of the best way to handle this in code. Here is the VB function declaration:
Private Function ReplaceDateTextNonBinary(psTable as String, psColumn as String, psColumnOffSet as String, psDateFormat as String, Optional psInterval as String = "n")
This function uses the optional parameter in the following DateAdd method call.
DateTime = DateAdd(psInterval, oSQL.Value(psColumnOffset), Date$)
Here is how I was planning to convert the function declaration to C# using the params keyword.
private static bool ReplaceDateTextNonBinary(string psTable, string psColumn, string pColumnOffset, string psDateFormat, params string psInterval)
I think this would work but I'm don't know how to code this that would take any date interval as a string. I was thinking of using a switch...case statement but that didn't seem very elegant.
Any thoughts.

You can use an optional parameter in C# just like this:
private static bool ReplaceDateTextNonBinary(string psTable,
string psColumn,
string pColumnOffset,
string psDateFormat,
string psInterval = "n")
If the optional parameter isn't passed, it'll get the value "n". Note that optional parameters must be listed last in the method signature. Also note this is a C# 4.0 feature and won't work with earlier versions of C# (in which case, simple overloading is probably your best bet).
See: Named and Optional Arguments (C# Programming Guide)
The prior to 4.0 way to do it would be something like this:
private static bool ReplaceDateTextNonBinary(string psTable,
string psColumn,
string pColumnOffset,
string psDateFormat)
{
return ReplaceDateTextNonBinary(psTable,
psColumn,
pColumnOffset,
psDateFormat,
"n");
}
private static bool ReplaceDateTextNonBinary(string psTable,
string psColumn,
string pColumnOffset,
string psDateFormat,
string psInterval)
{
// your implementation here
}

Related

how to use Any(char.IsDigit) to extract the int value [duplicate]

This question already has answers here:
How can I parse the int from a String in C#?
(4 answers)
Closed 3 months ago.
I have this line of code
bool containsInt = "Sanjay 400".Any(char.IsDigit)
What I am trying to do is extract the 400 from the string but
Any(char.IsDigit)
only returns a true value. I am very new to coding and c# especially.
As you already found out, you cannot use Any for extraction.
You would need to use the Where method:
List<char> allInts = "Sanjay 400".Where(char.IsDigit).ToList();
The result will be a list containing all integers/digits from your string.
Ok if you are interested in the value as integer you would need to convert it again to a string and then into an integer. Fortunately string has a nice constructor for this.
char[] allIntCharsArray = "Sanjay 400".Where(char.IsDigit).ToArray();
int theValue = Convert.ToInt32(new string(allIntCharsArray));
If you are using .NET 5 or higher you could also use the new cool TryParse method without extra string conversion:
int.TryParse(allIntCharsArray, out int theValue);
int result = int.Parse(string.Concat("Sanjay 400".Where(char.IsDigit)));
Use the Regex
var containsInt = Convert.ToInt32(Regex.Replace(#"Sanjay 400", #"\D", ""));
Regular expressions allow you to take only numbers and convert them into integers.

Make string comparison case-insensitive for .net winforms application [duplicate]

This question already has answers here:
Case insensitive 'Contains(string)'
(29 answers)
C# Case insensitive string comparison [duplicate]
(3 answers)
Closed 10 months ago.
Need to have string comparison case insensitive for .net winforms application. It is not a problem when strings are compared in my code, but I need this everywhere.
For ex.: there is combobox with items populated from SQL data, where value member is uppercase string, but entity field bound to this combobox as value is allowed to have value (string) lowercase. Same for the rest elements.
You cannot change the default comparison for strings in .net. .net is a case sensitive language. It has specific methods for comparing strings using different levels of case sensitivity, but (thank goodness) no global setting.
You can use this:
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
Or extension method:
public static class StringExtensions
{
public static bool Contains(this string source, string value, StringComparison compareMode)
{
if (string.IsNullOrEmpty(source))
return false;
return source.IndexOf(value, compareMode) >= 0;
}
}
and you can call it like this:
bool result = "This is a try".Contains("TRY",
StringComparison.InvariantCultureIgnoreCase);
Console.WriteLine(result);
Use
if (string1.ToLower().Equals(string2.ToLower()))
{
#something
}
without the code, there is no other advice i can offer you :/

Why does interpolating a const string result in a compiler error?

Why does string interpolation in c# does not work with const strings? For example:
private const string WEB_API_ROOT = "/private/WebApi/";
private const string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
From my point of view, everything is known at compile time. Or is that a feature that will be added later?
Compiler message:
The expression being assigned to 'DynamicWebApiBuilder.WEB_API_PROJECT' must be constant.
Thanks a lot!
Interpolated strings are simply converted to calls to string.Format. So your above line actually reads
private const string WEB_API_PROJECT = string.Format("{0}project.json", WEB_API_ROOT);
And this is not compile time constant as a method call is included.
On the other hand, string concatenation (of simple, constant string literals) can be done by the compiler, so this will work:
private const string WEB_API_ROOT = "/private/WebApi/";
private const string WEB_API_PROJECT = WEB_API_ROOT + "project.json";
or switch from const to static readonly:
private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
so the string is initialized (and string.Format called) at the first access to any member of the declaring type.
An additional explanation why string interpolation expressions are not considered constants is that they are not constant, even if all their inputs are constants. Specifically, they vary based on the current culture. Try executing the following code:
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
Console.WriteLine($"{3.14}");
CultureInfo.CurrentCulture = new CultureInfo("cs-CZ");
Console.WriteLine($"{3.14}");
Its output is:
3.14
3,14
Note that the output is different, even though the string interpolation expression is the same in both cases. So, with const string pi = $"{3.14}", it wouldn't be clear what code should the compiler generate.
UPDATE: In C# 10/.Net 6, string interpolations that only contains const strings can be const. So the code in the question is not an error anymore.
There is a discussion in Roslyn project at roslyn that finalize the following conclusion:
Read the excerpt:
It's not a bug, it was explicitly designed to function like this. You not liking it doesn't make it a bug.
String.Format isn't needed for concatenating strings, but that's not
what you're doing.
You're interpolating them, and String.Format is
needed for that based on the spec and implementation of how
interpolation works in C#.
If you want to concatenate strings, go
right ahead and use the same syntax that has worked since C# 1.0.
Changing the implementation to behave differently based on usage would
produce unexpected results:
const string FOO = "FOO";
const string BAR = "BAR";
string foobar = $"{FOO}{BAR}";
const string FOOBAR = $"{FOO}{BAR}"; // illegal today
Debug.Assert(foobar == FOOBAR); // might not always be true
Even the statement:
private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
The compiler raise an error:
"The name 'WEB_API_ROOT' does not exist in the current context".
The variable 'WEB_API_ROOT' should be defined in the same context
So, for the question of OP: Why does string interpolation is not working with const strings?
Answer: It's by C# 6 specs. for more details read .NET Compiler Platform ("Roslyn") -String Interpolation for C#
C# 10 (currently in preview at time of writing) will include the ability to use const interpolated strings, as long as the usage does not involve scenarios where culture may affect the outcome (such as this example).
So if the interpolation is simply concatenating strings together, it will work at compile time.
const string Language = "C#";
const string Platform = ".NET";
const string Version = "10.0";
const string FullProductName = $"{Platform} - Language: {Language} Version: {Version}";
This is now allowed in VS 2019 version 16.9, if the preview language version is selected (set <LanguageVersion>preview</LanguageVersion> in your project file).
https://github.com/dotnet/csharplang/issues/2951#issuecomment-736722760
in C# 9.0 or earlier we can not allow to use const with interpolated strings.
if you want to merge constant strings together, you will have to use concatenation and not interpolation.
const string WEB_API_ROOT = "/private/WebApi/";
const string WEB_API_PROJECT = WEB_API_ROOT + "project.json";
but from C# 10.0 Allow const interpolated strings as features and enhancements to the C# language.
C# 10.0 feature available in .NET 6.0 framework, in that we can able to use it.
see below code, currently C# 10.0 (Preview 5)
const string WEB_API_ROOT = "/private/WebApi/";
const string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
you can also checkout docs from official site What's new in C# 10.0
A constant used with string.Format would, by its nature, be intended to work with a specific number of arguments which each have a predetermined meaning.
In other words, if you create this constant:
const string FooFormat = "Foo named '{0}' was created on {1}.";
Then in order to use it you must have two arguments which are probably supposed to be a string and a DateTime.
So even before string interpolation we were in a sense using the constant as a function. In other words, instead of separating the constant, it might have made more sense to put it in a function instead, like this:
string FormatFooDescription(string fooName, DateTime createdDate) =>
string.Format("Foo named '{0}' was created on {1}.", fooName, createdDate);
It's still the same thing, except that the constant (string literal) is now located with the function and arguments that use it. They might as well be together, because the format string is useless for any other purpose. What's more, now you can see the intent of the arguments that are applied to the format string.
When we look at it that way, the similar use of string interpolation becomes obvious:
string FormatFooDescription(string fooName, DateTime createdDate) =>
$"Foo named '{fooName}' was created on {createdDate}.";
What if we have multiple format strings and we want to choose a particular one at runtime?
Instead of selecting which string to use, we could select a function:
delegate string FooDescriptionFunction(string fooName, DateTime createdDate);
Then we could declare implementations like this:
static FooDescriptionFunction FormatFoo { get; } = (fooName, createdDate) =>
$"Foo named '{fooName}' was created on {createdDate}.";
Or, better yet:
delegate string FooDescriptionFunction(Foo foo);
static FooDescriptionFunction FormatFoo { get; } = (foo) =>
$"Foo named '{foo.Name}' was created on {foo.CreatedDate}.";
}

How is String.Format method treated?

As is described at Microsoft Site ,String.Format arranges some String Variables into a single String and is another way how to concate string's in c#.
string.Format("Name = {0} Surname = {1}",name,surname);
My question is how does this work ?
Is this method a Special method ,and can i create a method similar to this one which accepts at every {n} only an Integer .
Or is this method interpreted in a different way by compiler ,if yes than how does the compiler accesses this method .
If it's possible i would like to see ,how does the compiler interpret this Method.
PS : How does it work ,when you can send as much parameters as you want to a method ?
[EDIT]
Does it mean ,that String.Format takes the first Parameter and filter's into with a Regex or Whatever tool (Split etc) to get where {Number} is and places there a String token from second params portion ?
Sending a variable number of parameters to a method is done like this:
public static string MyStringFormat(string formatString, params object [] args)
{
}
You can now pass as many parameters as you like to this:
MyStringFormat("{0}{1}",42,"Hello World")
MyStringFormat("{0}{1}{2}",42,"Hello World",999.9)
Within the method, these arguments are simply an array (of object in this case).
here are the docs on the params keyword.
As for writing you own method to accept numeric input like Format does, this would be one way (using regular expressions):
public static string MyStringFormat(string formatString, params object[] args)
{
var regex = new Regex("{([0-9]*)}");
return regex.Replace(formatString,m =>
{
int index = int.Parse(m.Groups[1].Value);
if(index<args.Length)
return args[index].ToString();
return String.Empty;
});
}
Live example: http://rextester.com/rundotnet?code=OMZC13551
It is a normal function.
It parses the string and calls ToString on the incoming parameters (if needed) in order to construct the new string.
The signature of the overload you have in your example is:
public static string Format(
string format,
params Object[] args
)
There is nothing to stop you from creating your own (though I would probably just delegate to the built in string.Format).
Use params: http://msdn.microsoft.com/en-us/library/w5zay9db.aspx
there is no magic there Cody, look at this method:
public static void UseParams(params int[] list)
{
for (int i = 0 ; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
Console.WriteLine();
}
you can call it passing as many int you like, it's the params parameter type :)
Edit:
params is very useful it allows us, for example, to pass to our logging wrapper all method's parameters values in a dynamic way without knowing how many of them each method has, the logger will then dump all those values one by one using Reflection to find out the parameter name as well.
The braces in the string are placeholders and a number within that denotes the index of argument it is to be replaced with.
Format is of type (string format, params object[] args) and it is the index in this object[] which is helpful.
(I think it internally uses the StringBuilder.AppendFormat) for substituting those values)
The signature of String.Format looks like this:
public static string Format (string format, params Object[] args)
Note the second parameter, marked with the params keyword. That one provides the functionality to add multiple parameters when calling the function. Inside the function you can access the parameters by index or iterating over args array:
public static string Format (string format, params Object[] args)
{
foreach (Object o in args)
Console.WriteLine(o);
}
Have a look at the C# Reference.

C# get string name's name [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to get variable name using reflection?
How to get the string name's name not the value of the string
string MyString = "";
Response.Write(MyString.GetType().Name);//Couldn't get the string name not the value of the string
The result should display back the string name "MyString"
I've found some suggested codes and rewrite it to make it shorter but still didn't like it much.
static string VariableName<T>(T item) where T : class
{
return typeof(T).GetProperties()[0].Name;
}
Response.Write(VariableName(new { MyString }));
I am looking another way to make it shorter like below but didn't how to use convert the current class so i can use them in the same line
Response.Write( typeof(new { MyString }).GetProperties()[0].Name);
While Marcelo's answer (and the linked to "duplicate" question) will explain how to do what you're after, a quick explanation why your code doesn't work.
GetType() does exactly what it says: it gets the Type of the object on which it is called. In your case, it will return System.String, which is the Type of the object referenced by your variable MyString. Thus your code will actually print the .Name of that Type, and not the name of the variable (which is what you actually want.)

Categories