C# Parse SqlDbType Conversion - c#

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.

Related

How to get the month name using Dictionary in 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];

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];

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?

How to store outcome of switch statement into an object in c#

Is it possible to create an object that stores the outcome of the switch statement in c#? Because my end goal is to compare the object in an if statement, and if that's true then it will print a writeline.
switch (results)
{
case 1:
checkingWriter.WriteLine("text");
break;
case 0:
checkingWriter.WriteLine("text");
error_Found = true;
break;
case -1:
checkingWriter.WriteLine("text");
error_Found = true;
break;
case -2:
checkingWriter.WriteLine("text");
error_Found = true;
break;
case -3:
checkingWriter.WriteLine("text");
error_Found = true;
break;
}
You are mixing both side effects and the computation of a value; this is a bad code smell and you might consider separating that logic.
To address your specific question: at this time there is no easy way to get a value computed by a particular switch case section out of the switch. However, this feature has been proposed for C# 8.0, so it seems likely that you'll get some version of this. See the link below for the proposal:
https://neelbhatt.com/2018/05/19/c-8-0-expected-features-part-iii-switch-statments/
Yes, something like (but very basic since we do not have any details):
var objectToCheck = ...; // Some initialized value or null
switch(...)
{
case ...:
objectToCheck = ...
break;
case ...:
objectToCheck = ...
break;
...
default:
Error handling
}
if (objectToCheck ==/.Equals(...) ) // Check object
create variable before switch statement begins, store the switch case result in variable. After switch ends, use the variable in the if condition.
var result = null;
switch (caseSwitch)
{
case 1:
result = fn1();
break;
case 2:
result = fn2();
break;
default:
Console.WriteLine("Default case");
break;
}
if(result == 'your condition')
do something
There are not enough details but may this works, or give you a new idea:
public class Foo
{
public static bool operator !=(Foo foo1, int results){
return results <= 0;
}
public static bool operator ==(Foo foo1, int results){
switch(results)
{
case 1:
Console.WriteLine("All gones good");
return false;
case 0:
Console.WriteLine("Nothing happend");
break;
case -1:
Console.WriteLine("Error 183");
break;
case -2:
Console.WriteLine("Fatal Error");
break;
case -3:
Console.WriteLine("The user doesn't exists");
break;
default:
return false;
}
return true;
}
}
And when you use it:
public static void Main()
{
Foo foo = new Foo();
int results = 0;
// makes some logic that fills results
if(foo == results){
Console.WriteLine("Do Something Custom Here");
}
results = -1;
if(foo == results){
Console.WriteLine("Do Another Something Custom Here");
}
}
It will give you in console something like this:
//Nothing happend
//Do Something Custom Here
//Error 183
//Do Another Something Custom Here

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