How to get the month name using Dictionary in C#? - c#

I have implemented the first three letters of the month to full name of the month in get Full Month function it is returned based on three letters .
But how to implemented in Dictionary concept Any one simplify modify this code given below code:
**public static string getFullMonth(string mthname)
{
string Mthname = "";
switch (mthname.ToUpper())
{
case "JAN":
Mthname ="January";
break;
case "FEB":
Mthname = "February";
break;
case "MAR":
Mthname = "March";
break;
case "APR:":
Mthname = "April";
break;
case "MAY":
Mthname = "May";
break;
case "JUN":
Mthname = "June";
break;
case "JUL":
Mthname = "July";
break;
case "AUG":
Mthname = "August";
break;
case "SEP":
Mthname = "September";
break;
case "OCT":
Mthname = "October";
break;
case "NOV":
Mthname = "November";
break;
case "DEC":
Mthname = "December";
break;
default:
Console.WriteLine("Invalid grade");
break;
}
return Mthname;
}**

simplify this code given below code
Yes, don't use a dictionary at all:
public static string GetFullMonth(string englishShortMonthName)
{
CultureInfo englishCulture = CultureInfo.InvariantCulture;
if (DateTime.TryParseExact(englishShortMonthName, "MMM", englishCulture, DateTimeStyles.None, out DateTime dt))
return dt.ToString("MMMM", englishCulture);
return englishShortMonthName;
}
Read about the month ("M", "m") format specifier

Look up Dictionary syntax. Ultimately you're looking for something like this:
var monthNames = new Dictionary<string, string>
{
{ "JAN", "January" },
{ "FEB", "February" },
...
}

Please find complete solution
public static string getFullMonth(string mthname)
{
var monthNames = new Dictionary<string, string>
{
{ "JAN", "January" },
{ "FEB", "February" },
...
}
return monthNames[mthname];
}
But above code looks weird So You should create dictionary globally and initialize in constructor.
Add only below line in getFullMonth function.
return monthNames[mthname];

Related

How to simplify a switch statement to reduce the cyclomatic complexity

I have a big switch statement that has a cyclomatic complexity of 31 and it must be refactorized to at least 25.
This is the error: Severity Code Description Project File Line Suppression State Suppression State
Error CA1502 'Worker.StartListening()' has a cyclomatic complexity of 31. Rewrite or refactor the method to reduce complexity to 25.
Thank you!
Here is the code:
public void StartListening()
{
var consumerSettingsSection= this.configurationManager.GetSection<ConsumerSettingsSection>("appZ/consumer");
foreach (var setting in consumerSettingsSection.QueueSettings)
{
var eventType = ConsumedEventType.NotSpecified;
switch (setting.Name)
{
case "A":
eventType = ConsumedEventType.A;
break;
case "B":
eventType = ConsumedEventType.B;
break;
case "C":
eventType = ConsumedEventType.C;
break;
case "D":
eventType = ConsumedEventType.D;
break;
case "E":
eventType = ConsumedEventType.E;
break;
case "F":
eventType = ConsumedEventType.F;
break;
case "G":
eventType = ConsumedEventType.G;
break;
case "H":
eventType = ConsumedEventType.H;
break;
case "I":
eventType = ConsumedEventType.I;
break;
case "J":
eventType = ConsumedEventType.J;
break;
case "K":
eventType = ConsumedEventType.K;
break;
case "L":
eventType = ConsumedEventType.L;
break;
default:
eventType = ConsumedEventType.NotSpecified;
break;
}
var consumer = new ChannelConsumer(setting, eventType);
consumer.MessageConsumed += this.Consumer_MessageConsumed;
consumer.StartConsuming();
}
}
You can try to simplify your code using Enum.TryParse method:
if (Enum.TryParse(setting.Name, true, out eventType))
return eventType;
else
return ConsumedEventType.NotSpecified;
You can parse the setting.Name string to ConsumedEventType, use the parsed value, otherwise return ConsumedEventType.NotSpecified value.
It's easier than maintaining a list of values. In terms of your code above you can write something like that
foreach (var setting in consumerSettingsSection.QueueSettings)
{
var eventType = ConsumedEventType.NotSpecified;
if (Enum.TryParse(setting.Name, true, out ConsumedEventType parsedEvent))
{
eventType = parsedEvent;
}
//rest of code
}
Or even easier
if (!Enum.TryParse(setting.Name, true, out ConsumedEventType eventType))
{
eventType = ConsumedEventType.NotSpecified;
}
Please, keep in mind that inline out variables are supported starting from C# 7
Use a Dictionary<string, ConsumedEventType>:
var d = new Dictionary<string, ConsumedEventType>()
{
{ "A", ConsumedEventType.A },
{ "B", ConsumedEventType.B },
{ "C", ConsumedEventType.C },
...
}
Now get the actual value that fits your settings.Name:
ConsumedEventType type;
var type = !d.ContainsKey(settings.Name)
ConsumedEventType.NotSpecified :
d[setting.sName];

How to get all the values within multiple curly braces

How do I split the following into an array of strings within the curly braces?
i have tried regex, but the pattern is thrown off because of the new line
string script = #"{
ABC
DEF
}
{
GHI
LMN
}
{
QWE
ERT
}
"
return an array of with the new line intact
["ABC\nDEF", "GHI\nLMN", "QWE\nERT"]
Hej i hope i got you right.
I know it is not the nices solution but it is something.
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp6
{
internal class Program
{
private enum Token
{
Open,
Close,
Char,
UnKnowChar,
Space,
NewLine,
}
private static void Main(string[] args)
{
var text = #"{
ABC
DEF
}
{
GHI
LMN
}
{
QWE
ERT
}
";
var strings = Parse(text).ToArray();
}
private static IEnumerable<string> Parse(string text)
{
var strings = new List<string>();
var tokens = GetTokens(text);
var opens = tokens.Select((token, index) => new {token, index})
.Where(list => list.token == Token.Open).ToList();
foreach (var open in opens)
{
var index = tokens.FindIndex(open.index, token => token == Token.Close);
var substring = text.Substring(open.index + 1, index - open.index - 1);
var trim = substring.Trim('\r', '\n', ' ');
strings.Add(trim.Replace(' '.ToString(), string.Empty));
}
return strings;
}
private static List<Token> GetTokens(string text)
{
var tokens = new List<Token>();
foreach (var _char in text)
switch (_char)
{
case ' ':
tokens.Add(Token.Space);
break;
case '\r':
case '\n':
tokens.Add(Token.NewLine);
break;
case '{':
tokens.Add(Token.Open);
break;
case '}':
tokens.Add(Token.Close);
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
tokens.Add(Token.Char);
break;
default:
tokens.Add(Token.UnKnowChar);
break;
}
return tokens;
}
}
}
Have a nice day.
Here's pretty much the same answer as h3e, except without adding the extra Tokens class and enum. We can just treat the string as an array of characters, get the indexes of all the opening and closing braces, and then grab the substrings from between them:
private static IEnumerable<string> GetItems(string text)
{
var items = new List<string>();
var openBraceIndexes = text.Select((chr, index) => new { chr = chr, index })
.Where(item => item.chr == '{').ToList();
var closeBraceIndexes = text.Select((chr, index) => new { chr, index })
.Where(item => item.chr == '}').ToList();
if (openBraceIndexes.Count != closeBraceIndexes.Count)
{
throw new FormatException("text contains an unequal number of open and close braces");
}
for (int i = 0; i < openBraceIndexes.Count; i++)
{
var startIndex = openBraceIndexes[i].index + 1;
var length = closeBraceIndexes[i].index - startIndex;
items.Add(text.Substring(startIndex, length).Trim());
}
return items;
}

Finding all objects on which method X is executed

Let's assume there are a lot of code blocks like this in my solution:
switch (Key)
{
case "A":
displayName = "Title1";
break;
case "B":
displayName = "Title2";
break;
case "C":
displayName = "Title3";
break;
default:
throw new NotSupportedException();
}
displayName = displayName.X();
Is there a possibility to get all strings in code on which method X can be executed?

C# Parse SqlDbType Conversion

Is there any way to do something like this:
(SqlDbType.Int).Parse(dtbDataTable.Rows[0]["Id"])
Posting back my workaround:
public static string ParseValue(SqlDbType psdtParameter, string pstrValue, string pstrDateFormat = null)
{
object objReturn = new object();
if (pstrValue != "")
{
switch (psdtParameter.ToString())
{
case "BigInt":
objReturn = TypeDescriptor.GetConverter(typeof(Int64)).ConvertFromString(pstrValue);
break;
case "Bit":
objReturn = TypeDescriptor.GetConverter(typeof(Boolean)).ConvertFromString(pstrValue);
break;
case "NText":
case "NVarChar":
case "VarChar":
case "NChar":
case "Text":
case "Char":
objReturn = TypeDescriptor.GetConverter(typeof(String)).ConvertFromString(pstrValue);
break;
case "SmallDateTime":
case "DateTime":
objReturn = DateTime.ParseExact(pstrValue, pstrDateFormat, CultureInfo.InvariantCulture);
//TypeDescriptor.GetConverter(typeof(DateTime)).ConvertFromString(pstrValue);
break;
case "Money":
case "SmallMoney":
case "Decimal":
objReturn = TypeDescriptor.GetConverter(typeof(Decimal)).ConvertFromString(null, CultureInfo.InvariantCulture, pstrValue);
break;
case "Float":
objReturn = TypeDescriptor.GetConverter(typeof(Double)).ConvertFromString(pstrValue);
break;
case "Binary":
case "VarBinary":
case "Timestamp":
case "Image":
objReturn = TypeDescriptor.GetConverter(typeof(Byte[])).ConvertFromString(pstrValue);
break;
case "Int":
objReturn = TypeDescriptor.GetConverter(typeof(Int32)).ConvertFromString(pstrValue);
break;
case "Real":
objReturn = TypeDescriptor.GetConverter(typeof(Single)).ConvertFromString(pstrValue);
break;
case "SmallInt":
objReturn = TypeDescriptor.GetConverter(typeof(Int16)).ConvertFromString(pstrValue);
break;
case "TinyInt":
objReturn = TypeDescriptor.GetConverter(typeof(Byte)).ConvertFromString(pstrValue);
break;
}
return objReturn.ToString();
}
else
{
return null;
}
}
Tks!
Unfortunately no. SqlDbType is an enum, so (SqlDbType.Int) actually boils down to an integer value, not a type. The only way I can think of to do this is some sort of switch statement:
switch (SqlDbType dbType)
{
case SqlDbType.Int:
int value = Int32.Parse(dtbDataTable.Rows[0]["Id"]);
//Do stuff with this value
//repeat for other types
}
I think that would be tough to do, and it's not the most readable way. I handle this via extension methods to help with TinyInt, SmallInt, and nullable values across the board. E.g.:
using (var dr = new SafeDataReader(cmd.ExecuteReader()) {
while (dr.Read()) {
int? id = dr.GetNullableIntFromSqlTinyInt(0);
// Other stuff like that to handle type conversions
}
}
SafeDataReader is part of the CSLA business object framework, but you could implement your own DataReader if you would like. It's a lot more legible and encapsulates all the parsing logic behind the scenes to the extension method.

I want something like the switch statement (but different of course)

Is there a C# construct like the switch statement that allows control to fall through the next level? I have something like this:
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var result = new List<string>();
switch (severity.ToUpper())
{
case "ALL":
result.Add("ALL");
case "DEBUG":
result.Add("DEBUG");
case "INFO":
result.Add("INFO");
case "WARN":
result.Add("WARN");
case "ERROR":
result.Add("ERROR");
case "FATAL":
result.Add("FATAL");
case "OFF":
result.Add("OFF");
default:
break;
}
return result;
}
...which clearly does not work in C#, (Control cannot fall through from one case label...) yet it seems to me like it should. I know it expects breaks in there, but that would not give me the data flow I'm looking for. What can be done to make this happen the way I'd like?
In your case you can emulate "falling case" with a little bit of LINQ:
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var result = new List<string>()
{ "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
return result.SkipWhile(l => l != severity.ToUpper()).ToArray();
}
Along with gotos, etc, you could do with this an enum and a bit of linq:
public static IEnumerable<Severity> SeverityOrHigher(Severity severity)
{
var value = (int) severity;
return Enum.GetValues(typeof (Severity))
.Cast<int>()
.Where(i => i >= value)
.Select(i => (Severity) i);
}
public enum Severity
{
All = 0,
Trace = 1,
Debug = 2,
Information = 3,
Warning = 4,
Error = 5,
Fatal = 6
}
It is not the optimal solution but you could use the goto statement like this:
switch (severity.ToUpper())
{
case "ALL":
result.Add("ALL");
goto case "DEBUG";
case "DEBUG":
result.Add("DEBUG");
goto case "INFO";
case "INFO":
result.Add("INFO");
goto case "WARN";
case "WARN":
result.Add("WARN");
goto case "ERROR";
case "ERROR":
result.Add("ERROR");
goto case "FATAL";
case "FATAL":
result.Add("FATAL");
goto case "OFF";
case "OFF":
result.Add("OFF");
break;
default:
break;
}
Use goto:
switch (severity.ToUpper())
{
case "ALL":
result.Add("ALL");
goto case "DEBUG";
case "DEBUG":
result.Add("DEBUG");
goto case "INFO";
case "INFO":
result.Add("INFO");
goto case "WARN";
case "WARN":
result.Add("WARN");
goto case "ERROR";
case "ERROR":
result.Add("ERROR");
goto case "FATAL";
case "FATAL":
result.Add("FATAL");
goto case "OFF";
case "OFF":
result.Add("OFF");
break;
default:
break;
}
Microsoft (implicitly) recommends this use: http://msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx
#nemesv's Linq answer is way better solution but if you want to do it with switch you could do like this and will get same result.
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var lastFound = -1;
var severityList = new List<string>() { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
var results = new List<string>();
foreach (var t in severityList)
{
if (lastFound > -1)
{
for (var index = lastFound + 1; index < severityList.Count; index++)
{
results.Add(severityList[index]);
}
return results;
}
switch (severity.ToUpper())
{
case "ALL":
results.Add(severity);
lastFound = 0;
break;
case "DEBUG":
lastFound = 1;
results.Add(severity);
break;
case "INFO":
lastFound = 2;
results.Add(severity);
break;
case "WARN":
lastFound = 3;
results.Add(severity);
break;
case "ERROR":
lastFound = 4;
results.Add(severity);
break;
case "FATAL":
lastFound = 5;
results.Add(severity);
break;
case "OFF":
lastFound = 6;
results.Add(severity);
break;
}
}
return results;
}
Test:
var list = SeverityOrHigher("ALL");
foreach (var severity in list)
{
Console.WriteLine(severity);
}
Console.ReadKey();
Does not look very nice, but could do the job for you:
string s = severity.ToUpper();
result.add("OFF");
if (s == "OFF")
return result;
result.add("FATAL");
if (s == "FATAL")
return result;
result.add("ERROR");
if (s == "ERROR")
return result;
// ...
result.add("ALL");
return result;
I'd go with somehting like creating another list which represents all valid severities and checking if the input severity is one of them:
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var result = new List<string>();
var severities = new List<string> { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
severity = severity.ToUpper();
if (severities.Contain(severity))
result.Add(severity);
return result;
}

Categories