I am using gridview's default update method in which it allows me to update row in gridview itself by converting cells into textboxes.
I want to check validations that if a particular textbox (cell) remains empty or blank then it should not update its value.
For that i have written following code:
string.IsNullOrEmpty(e.NewValues[0].ToString())
But it gives an error like object reference not set to an instance of an object. May be it can not convert null value of e.Newvalues[0] to string.
All answers are appreciated in advance.
You could do this:
e.NewValues[0] == null || e.NewValues[0].ToString() == string.Empty
If e.NewValues[0] is already a string, you could just do this:
string.IsNullOrEmpty(e.NewValues[0])
Update as of C# 6, you could also use:
string.IsNullOrEmpty(e.NewValues[0]?.ToString())
Or even:
$"{e.NewValues[0]}" == string.Empty
Another way:
String.IsNullOrEmpty(Convert.ToString(e.NewValues[0]));
A bit of (probably unneeded) explanation:
Convert.ToString() will return null for a (string)null, and an empty string for an (object)null (or any other null).
Either case will give the expected result, because we're checking with String.IsNullOrEmpty().
In any case, its behaviour is the same as someValue.ToString() except it handles the cases where someValue is null.
Another (wasteful) way to do it is with a singleton with an overridden ToString and ?? (overkill but it lets me use ?? :P)
(e.NewValues[0] ?? Empty._).ToString();
The code for the singleton is here:
public sealed class Empty
{
private static readonly Lazy<Empty> lazy =
new Lazy<Empty>(() => new Empty());
public override string ToString()
{
return "";
}
public static object _ { get { return lazy.Value; } }
private Empty()
{
}
}
You can use this piece of code
(e.NewValues[0] == null) ? string.Empty : e.NewValues[0].ToString()
The above code will will return the string equivalent if not null, otherwise it will return empty string.
Otherwise you can use following code. This will handle the null case.
string.IsNullOrEmpty(Convert.ToString( e.NewValues[0] )
You'll need to check that e.NewValues[0] isn't null prior to doing a .ToString() on it.
protected void grd_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = grd.Rows[e.RowIndex];
for (int i = 0; i <= row.Cells.Count; i++)
{
String str = ((TextBox)(row.Cells[i].Controls[0])).Text;
if (!string.IsNullOrEmpty(str))
{
//Your Code goes here ::
}
}
}
Related
I have a method with two optional parameters. I want to shorten my code.
here is my code:
DataTable dtList;
if (!duration.ContainsKey("startDay") && duration.ContainsKey("endDay"))
{
dtList = GetAllReservation();
}
else if (duration.ContainsKey("startDay") && !duration.ContainsKey("endDay"))
{
dtList = GetAllReservation(duration["startDay"]);
}
else
{
dtList = GetAllReservation(duration["startDay"], duration["endDay"]);
}
is there any way to shorten this code to something like this:
dtList = GetAllReservation(duration["startDay"], duration?["endDay"]);
this is my method GetAllReservation:
public static DataTable GetAllReservation(string start = "1397/01/01", string end = "1400/12/29") =>
DataAccess.Select($"Exec ReservationList '{start}', '{end}'", ref _methodState);
Do not define the parameter default to be the business default. Define the parameter default to be null, which signifies a lack of value. The method itself should check for the parameter default and substitute the business default as needed.
public static DataTable GetAllReservation(string start = null, string end = null)
{
if (start == null) start = _config.GetDefaultStartDate();
if (end == null) end = _config.GetDefaultEndDate();
DataAccess.Select($"Exec ReservationList '{start}', '{end}'", ref _methodState);
}
Also, you can write an extension method on Dictionary:
public static string GetStringOrNull(this Dictionary<string,string> source, string key)
{
if (!source.ContainsKey(key)) return null;
return source[key];
}
Which allows you to shorten your call to this:
GetAllReservation(duration.GetStringOrNull("startDay"), duration.GetStringOrNull("endDay"));
Try this one,
dtList = GetAllReservation(duration.ContainsKey("startDay")?duration["startDay"]:"1397/01/01",duration.ContainsKey("endDay")?duration["endDay"]:"1400/12/29");
you can do like this
string stDate = duration.ContainsKey("startDay") ? duration("startDay") : null;
string edDate = duration.ContainsKey("endDay") ? duration("endDay") : null;
dtList = GetAllReservation(stDate ,edDate );
public static DataTable GetAllReservation(string start = null, string end = null)
{
if (start == null) start = ""; //Set default value
if (end == null) end = "";//Set default value
//..... further code
}
In my opinion, good programming does not necessarily means shorter code. It may be of value to think of each case as a separate method. If each method has a specific function, the logic of each method becomes simpler. It also reduces coding errors and possible exceptions.
In this case you have 3 methods. Each method does a slightly different job depending on the number of parameters, but at the end the return the same sort of result. This looks like a good case of method overloading. I believe that method overloading is good as long as the method(s) really do the same core function only with different parameters. Some think that method overloading is Evil.
No need of optional parameters here (if you really want shorter version of your code and may be more readable):
string startDayDuration = duration.ContainsKey("startDay") ? duration["startDay"] : "1397/01/01";
string endDayDuration = duration.ContainsKey("endDay") ? duration["endDay"] : "1400/12/29";
dtList = GetAllReservation(startDayDuration, endDayDuration);
then your method:
public static DataTable GetAllReservation(string start, string end) =>
DataAccess.Select($"Exec ReservationList '{start}', '{end}'", ref _methodState);
Here's code I write to check if properties in my viewmodel are null or not before attempting to update the database
var channel = _context.Channels.FirstOrDefault(x => x.Id == viewModel.Id);
if (!string.IsNullOrEmpty(viewModel.Part))
{
channel.Part = viewModel.Part;
}
if (!string.IsNullOrEmpty(viewModel.IndexName))
{
channel.IndexName = viewModel.IndexName;
}
if (viewModel.MeasurementId != null)
{
channel.MeasurementId = viewModel.MeasurementId;
}
if (!string.IsNullOrEmpty(viewModel.Direction))
{
channel.Direction = viewModel.Direction;
}
The code is working fine but I use alot of if statements here which for me doesn't look really effective. Can you suggest me changes like using other syntax or structures rather than if statement to make my code more concise and abit more "pro"?
As long as your channel object's properties do not have any side-effects other than changing a value (ie, firing events), you could do this:
string PickNonEmptyOrDefault(string value, string deflt)
{
return String.IsNullOrEmpty(value) ? deflt : value;
}
...
channel.Part = PickNonEmptyOrDefault(viewModel.Part, channel.Part);
channel.IndexName = PickNonEmptyOrDefault(viewModel.IndexName, channel.IndexName);
etc.
By the way, I wanted to know if there was a way this could be done without accidentally side effecting your property. The trick is to use reflection and to use a PropertyInfo object to do your work:
class Foo
{
public string Bar { get; set; }
public string Baz { get; set; }
public override string ToString()
{
return (Bar ?? "") + " " + (Baz ?? "");
}
}
delegate void propsetter(string prop, string value);
private static void SetOnNonEmpty(PropertyInfo pi, Object o, string value)
{
if (pi.PropertyType != typeof(string))
throw new ArgumentException("type mismatch on property");
if (!String.IsNullOrEmpty(value))
pi.SetValue(o, value);
}
static void Main(string[] args)
{
var myObj = new Foo();
myObj.Baz = "nothing";
PropertyInfo piBar = myObj.GetType().GetProperty("Bar");
PropertyInfo piBaz = myObj.GetType().GetProperty("Baz");
SetOnNonEmpty(piBar, myObj, "something");
SetOnNonEmpty(piBaz, myObj, null);
Console.WriteLine(myObj);
}
output something nothing
I honestly don't recommend doing this as it doesn't really add to the readability and feels pretty gross.
I'd be more inclined to write a chunk of code that reflects across the properties of your view model and calls a Func<string, string> to get the corresponding property name in your data model and then if that returns non-null and the property types match, call the getter on the view object and pass it to the setter on the data object.
And I would only do this if I was doing this a significant number of times.
If it's just the if that bothers you you could use the conditional operator:
channel.Part = string.IsNullOrEmpty(viewModel.Part) ?
channel.Part : viewModel.Part;
etc.
of course that always calls the set accessor for Part, which is fine unless there's logic in it (change tracking, etc.) that would be bad if it were called when the value doesn't really change.
You could also refactor the conditional operator to a method, but there's no other way to conditionally set the value without using an if.
Your code is fine. Even Jon Skeet uses if statements.
If you want the best performing code, keep it like this. If you want to make your code look pro, use any suggestion done by others here. My opinion: keep it as is.
There is absolutely nothing wrong with the code you have written.
If your objective is less lines of code, you can do this, however I think it will just add unnecessary complexity.
channel.Part = string.IsNullOrWhiteSpace(viewModel.Part) ? channel.Part : viewModel.Part;
channel.IndexName = string.IsNullOrWhiteSpace(viewModel.IndexName) ? channel.IndexName: viewModel.IndexName;
channel.MeasurementId = viewModel.MeasurementId == null ? channel.MeasurementId : viewModel.MeasurementId;
channel.Direction = string.IsNullOrWhiteSpace(viewModel.Direction) ? channel.Direction : viewModel.Direction;
Note I have switched your call from IsNullOrEmpty to IsNullOrWhiteSpace
A string with the value of " " (one or more whitespace) will get through a IsNullOrEmpty check which you probably dont want.
You can also use the coalesce operator for your nullable types (but not empty strings) like this...
channel.MeasurementId = viewModel.MeasurementId ?? channel.MeasurementId;
If those are fields and not properties, you can use something like this:
void ReplaceIfNotEmpty(ref string destination, string source)
{
if (!string.IsNullOrEmpty(source))
{
destination = source;
}
}
and then just
ReplaceIfNotEmpty(ref channel.Part, viewModel.Part);
_callReportCode = reader["Call Report Code"].ToString();
I am attempting to handle the possibility for the object I am calling ToString on to be NULL.
I am going to be using the above statement with several variables and I dont want to make an individual try/catch for each one... what is the best way to do null checking for strings.
Other datatypes ive been doing this:
int.TryParse(reader["Account Number"].ToString(), out _accountNumber);
In this code "reader" refers to a SqlDataReader but thats not really important for this question.
Use the null-coalescing operator: ??
callReportCode = (reader["Call Report Code"] ?? "").ToString();
If the data in your field is DBNull.Value (rather than null), this will still work, because DBNull.Value is not null, so the ?? won't be used, and DBNull.Value.ToString() is "", which is what you'd want.
Convert.ToString(reader["Call Report Code"]);
It will return string.Empty if the value is null.
Source: http://msdn.microsoft.com/en-us/library/astxcyeh.aspx
Update: it also works with DBNull, I've just verified.
Update 2: I decided to bring a more complete test here, just to be sure:
DBNull dbNull = null;
DBNull dbNullEmpty = DBNull.Value;
string stringNull = null;
string stringEmpty = string.Empty;
var outcome1 = Convert.ToString(dbNull);//Empty string
var outcome2 = Convert.ToString(dbNullEmpty);//Empty string
var outcome3 = Convert.ToString(stringNull);//NULL
var outcome4 = Convert.ToString(stringEmpty);//Empty string
If your string is nullable, you need to check the value returned from the SqlDataReader against DBNull.Value:
_callReportCode = reader["Call Report Code"] as string;
If the object returned by reader["Call Report Code"] is not a string, it's DBNull.Value, so the as cast is going to set the value of _callReportCode to null as well.
If you must set the string to a non-null in case the database value is missing, add ??, like this:
_callReportCode = (reader["Call Report Code"] as string) ?? string.Empty;
My suggestion is to never convert ToString when the data isn't a string, and if the data is already a string, then calling ToString is redundant, and a cast is all that's required.
I am making an assumption that the datatype in the database is integer, in which case, you can use a nullable int.
int? accountNumber = reader["Account Number"] == DBNull.Value ? null : (int?)reader["Account Number"];
I have made an extension method to do just this thing.
public static class SqlDataReaderExtensions
{
public static T Field<T>(this SqlDataReader reader, string columnName)
{
object obj = reader[columnName];
if (obj == null)
{
throw new IndexOutOfRangeException(
string.Format(
"reader does not contain column: {0}",
columnName
)
);
}
if (obj is DBNull)
{
obj = null;
}
return (T)obj;
}
}
Usage
int? accountType = reader.Field<int?>("Account Number"); // will return NULL or the account number.
The easiest way I have found is
_callReportCode = reader["Call Report Code"] + "";
i have some easiest and common Method.
public static string ToNULLString(this string Values)
{
if (string.IsNullOrEmpty(Values))
{
return "";
}
else
{
return Values.ToString();
}
}
use in C#
string item = null;
string value = item.ToNULLString();
you could create a method that you call when you want to make the check.
This way you have to type the try catch only once...
or you can create an extension method for string class to do this
_callReportCode = Convert.ToString(reader["Call Report Code"]) should ensure there are no null there.
Use following line of code:
_callReportCode = String.IsNullorEmpty(reader["Call Report Code"]) ?
String.Empty :
reader["Call Report Code"].ToString();
instead of the following line:
_callReportCode = reader["Call Report Code"].ToString();
I like using a combination of the null-coalescing operator and the null conditional operator:
string nn = MyObject.myNullableVar?.ToString() ?? "";
it's basically the same as this
string ss = (MyObject.MyNullableVar == null) ? "" : MyObject.MyNullableVar.ToString();
but shorter.
You can perform a check using String.IsNullOrEmpty() to ensure that it isn't going to be null, or you could write an extension method to perform some action if it's not null and another / nothing if it is.
I have the following code to enter a previous value into a DataGridView cell. If on row 0 and col 2 or greater, the val to the left, otherwise the value directly above:
private void dataGridViewPlatypi_CellEnter(object sender, DataGridViewCellEventArgs args)
{
// TODO: Fails if it sees nothing in the previous cell
string prevVal = string.Empty;
if (args.RowIndex > 0)
{
prevVal = dataGridViewPlatypi.Rows[args.RowIndex - 1].Cells[args.ColumnIndex].Value.ToString();
} else if (args.ColumnIndex > 1)
{
prevVal = dataGridViewPlatypi.Rows[args.RowIndex].Cells[args.ColumnIndex-1].Value.ToString();
}
dataGridViewPlatypi.Rows[args.RowIndex].Cells[args.ColumnIndex].Value = prevVal;
}
This works great as long as there is a value to be seen and copied over. If the cell is blank, though, I get:
System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object.
I'm guessing this is an opportunity to use the null coalesce operator, but (assuming my guess is good), just how do I implement that?
Try something like this:
string s = SomeStringExpressionWhichMightBeNull() ?? "" ;
Easy!
Assuming Value is what is null (not entirely clear from your post) you can do
object cellValue =
dataGridViewPlatypi.Rows[args.RowIndex - 1].Cells[args.ColumnIndex].Value;
prevValue = cellValue == null ? string.Empty : cellValue.ToString()
Use a method such as:
public static class MyExtensions
{
public static string SafeToString(this object obj)
{
return (obj ?? "").ToString();
}
}
then you can use it like:
object obj = null;
string str = obj.SafeToString();
or as an example from your code:
prevVal = dataGridViewPlatypi.Rows[args.RowIndex - 1].Cells[args.ColumnIndex].Value.SafeToString();
This creates an extension method, so if you add a using for the namespace that the extensions class is in all objects will appear to have a SafeToString method in intellisense. The method isn't actually an instance method, it just appears as one, so instead of generating a null reference exception if the object is null it simply passes null to the method, which treats all null values as empty strings.
Here's the scenario...
if (entry.Properties["something"].Value != null)
attribs.something = entry.Properties["something"].Value.ToString();
While effective and working correctly, this looks ugly to me. If I don't check for a null before performing the ToString() then it throws an exception if the property was null. Is there a better way to handle this scenario?
Much appreciated!
Update 8 years later (wow!) to cover c# 6's null-conditional operator:
var value = maybeNull?.ToString() ?? String.Empty;
Other approaches:
object defaultValue = "default";
attribs.something = (entry.Properties["something"].Value ?? defaultValue).ToString()
I've also used this, which isn't terribly clever but convenient:
public static string ToSafeString(this object obj)
{
return (obj ?? string.Empty).ToString();
}
If you are targeting the .NET Framework 3.5, the most elegant solution would be an extension method in my opinion.
public static class ObjectExtensions
{
public static string NullSafeToString(this object obj)
{
return obj != null ? obj.ToString() : String.Empty;
}
}
Then to use:
attribs.something = entry.Properties["something"].Value.NullSafeToString();
Convert.ToString(entry.Properties["something"].Value);
Adding an empty string to an object is a common idiom that lets you do null-safe ToString conversion, like this:
attribs.something = ""+entry.Properties["something"].Value;
When entry.Properties["something"].Value is null, this quietly returns an empty string.
Edit: Starting with C# 6 you can use ?. operator to avoid null checking in an even simpler way:
attribs.something = entry.Properties["something"].Value?.ToString();
// ^^
Can you not do:
attribs.something = entry.Properties["something"].Value as string;
attribs.something = String.Format("{0}", entry.Properties["something"].Value);
Not sure about performance though...
In C# 6.0 you can do it in a very elegant way:
attribs.something = entry.Properties["something"].Value?.ToString();
And here is an article about new null-conditional operator.
As a variation to RexM's answer:
attribs.something = (entry.Properties["something"].Value ?? attribs.something).ToString()
The only downside would be that the attribs.something would be assigned a value (itself, in this example) even if entry.Properties["something"].Value was null - which could be expensive if the .something property did some other processing and/or this line executes a lot (like in a loop).
To do precisely what you're trying to do a helper method can always be used:
CopyIfNotNull(entry.Properties["something"].Value, out attribs.something);
void CopyIfNotNull(string src, out string dest)
{
if(src != null)
dest = src;
}
Is it somehow possible to do something like
Dale Ragan's answer above, but overriding ToString() instead of creating a new NullSafeToString() method? I'd like this (or returning "null") to be the default behaviour. The compiler (Visual C# 2010 Express) doesn't complain when I add the following method to public static class ObjectExtensions, but the method doesn't get called...
public static String ToString(this Object obj)
{
if (obj == null)
{
return "null";
}
else
{
return obj.GetType().Name;
}
}
attribs.something = string.Format("{0}",entry.Properties["something"].Value)
How about using an auxiliary method like this:
attribs.something = getString(
entry.Properties["something"].Value,
attribs.something);
static String getString(
Object obj,
String defaultString)
{
if (obj == null) return defaultString;
return obj.ToString();
}
Alternatively, you could use the ?? operator:
attribs.something =
(entry.Properties["something"].Value ?? attribs.something).ToString();
(note the redundant ToString() call when the value is null)