Optimizing code structure C# - c#

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

Related

C# get propery value from string path

Given any object, I want to be able to retrieve the value of a property and any "depth".
var name = myObject.GetValue<String>("Name")
or
var father_name = myObject.GetValue<String>("Father.Name")
This is easy and I'm able do achieve it with the following code:
public static T GetValue<T>(this Object obj, String fqname)
{
try
{
Object value = obj;
foreach (var prop in fqname.Split('.').Select(s => value.GetType().GetProperty(s)))
{
value = prop.GetValue(value, null);
}
if (value is T)
{
return (T)value;
}
else
{
// if the type requested is not the same as the stored, attempt a blind conversion
var converter = TypeDescriptor.GetConverter(typeof(T));
return (T)converter.ConvertFromInvariantString(value.ToString());
}
}
catch (NotSupportedException)
{
throw new InvalidCastException($"Cannot convert value to reuested type");
}
}
Now the problem is that this doesn't work for arrays, like:
var main_street = myObject.GetValue<String>("Addresses[0].StreetName")
Not even for the cases of arrays of arrays and so on...
I can start adding these conditions and special cases to my code but before that I figured, as C# already does this, maybe we could leverage some code parsing strategy, Roslyn, ... don't know, something that doesn't feel like reinventing the wheel and supports as many cases as possible.
Any ideas?

Is there a shorthand way to return values that might be null?

How can I write a shorthand of the following scenario?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
Using null-coalescing operator ( ?? ):
get
{
_rows = _rows ?? new List<Row>();
return _rows;
}
OR (less readable):
get { return _rows ?? (_rows = new List<Row>()); }
The ?? operator is called the null-coalescing operator. It returns the
left-hand operand if the operand is not null; otherwise it returns the
right hand operand.
This is the lazy initialization pattern so the straightforward way would be to use the Lazy<T> class.
class Foo
{
Lazy<List<Row>> _rows;
public Foo()
{
_rows = new Lazy(() => new List<Row>());
}
public List<Row> Rows
{
get { return _rows.Value; }
}
}
This has the additional advantage that it doesn't "pollute" the getter with initialization logic.
I suggest ternary operator
get {
return _rows == null ? _rows = new List<Row>() : _rows;
}
Or since empty List<Row> doesn't bring much overhead why not get rid of explicit _row field and implement just read-only property (C# 6.0 syntax):
public IList<Row> Rows {get;} = new List<Row>();
Here's a better idea: Prevent _rows from ever being null.
Make your constructor initialize the variable:
public MyClass()
{
this._rows = new List<Row>();
}
and then your property is just
get
{
return this._rows;
}
Make sure that if you need to "clear" the variable, you always call its Clear method or assign a new empty list instead of assigning null. Maybe encode that operation in a method if you really need to make it clear and consistent throughout the class.
This is much more logical. If your variable should never be null, it should never be null. It also neatly avoids both the conditional and the issue of having a getter modify state.
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());
As others have said, you can use the null-coalescing operator in this scenario.
get
{
return _rows ?? (_rows = new List<Row>());
}
It's worth noting that this is the kind of change that ReSharper is great at suggesting (they call it a quick-fix).
In your example it will put a small squiggle under the if statement. Hovering over it reveals a suggestion for how the code could be changed/simplified.
A couple of clicks later, and the change is implemented.
Like this for example:
get{ return _rows ?? (_rows = new List<Row>()); }
If you want your code to behave like your current code, lazily initialising your backing field when the property is accessed, then yes, you can make it shorter. You can rename your backing field, as answered already use ?? to put everything in a single expression, and when you have that single expression, use C# 6's new property syntax to avoid writing get and return:
List<Row>_;List<Row> Rows=>_??(_=new List<Row>());
Hopefully, well before you get to this point, you will see that you've turned easy-to-understand code that does exactly what you want into a horrible mess that you would never want to maintain.
Just keep your code exactly as it is. You can make it shorter, as shown, but that doesn't make it any better.
If the problem is that it takes more time to write, because you keep typing the same code over and over, many IDEs provide some feature to insert templates, snippets, or whatever term they use for it. This lets you define something along the lines of
{Type} {Field};
public {Type} {Property} {
get {
if ({Field} == null) {
{Field} = new {Type}();
}
return {Field};
}
}
where your editor will then prompt you for the specific {Type}, {Field}, {Property}, without having to type it again each time.
return _rows ?? (_rows = new List<Row>());
If you really wanted to shorten it I would just remove the extra brackets.
get
{
if (_rows == null)
_rows = new List<Row>();
return _rows;
}
You can do this by any of the following ways:
Conditional operator (?:)
Null-coalescing operator ( ?? )
With Conditional operator
get {
return _rows == null ? new List<Row>() : _rows;
}
Null-coalescing operator
get {
return _rows ?? new List<Row>();
}

efficient way to check for changes in a "calculation" class

I have the following "calculation" class.
public class Foo
{
private int? _sum = 0;
public int Sum
{
get
{
if (_sum == null)
_sum = 1 + 1; //simple code to show "some" calculation happens...
return _sum.GetValueOrDefault();
}
}
}
In this example there is only 1 Field/Member but in my real class there are around 50 Members, that all look similar just with different value calculations.
In the class I also have a Recalc method.
This Recalc method does 4 things
Save the old values
set all fields to null
calls the getter of every member
Checks if the old values differ from the newvalues and does related stuff
I am not sure whats the best way to store the old values and check for changes with the new values.
My current implementation is this:
public string GetValuesKey()
{
//again this method only handles the 1 Member and not all 50 in real app its string.Format("{0}|{1}|{2}|...{49}|{50}|", ....);
return string.Format("{0}|", this.Sum);
}
public void Recalc()
{
var oldValues = GetValuesKey();
//set all fields to null
//call the getters
var newValues = GetValuesKey();
if (oldValues != newValues)
{
//something changed...
}
}
But with this code there is a memory/performance issue since I am doing boxing with the struct (decimal) writing to a reference type (string).
I kind of want to prevent doing 50 additional fields (something like _oldSum) for all the members.
I just need to check if any member has changed during the Recalc procedure.
Just in Case, I cannot do the following code.
public void Recalc()
{
var changes = false;
var oldValue = this.Sum;
_sum = null;
var newValue = this.Sum;
if (oldValue != newValue)
changes = true;
//check next member
oldValue = this.Sum2;
_sum2 = null;
newValue = this.Sum2;
if (oldValue != newValue)
changes = true;
//check next member and so on...
}
Since I need to set all fields to null first and only AFTER all of them have been set to null I can execute the getters, since the members are dependant on each other for exmple if the Sum Member would aggregate two other members and they havent been set to null first they would still have old values.
So I need a way to store something that represents all values before setting the fields null and after calling the getter of the members a way to check for changes.
Any help is welcome.
Edit:
Here is the code, I wrote to test performance/memory:
http://pastebin.com/3WiNJHyS
Instead of combining all values in a string and have some pefomance hit on that string construction - put all values in array (of decimal), then set all fields to null, make your calculation and compare arrays of old and new values.
If you don't want to write yourself all the 50 _oldValue fields, the only alternative is to use Reflection, that implies some boxing/unboxing, so performance will not be the best possible.
Anyway, in the following implementation I assume that in the Foo class the members that are involved in the calculation are all and the only ones that are properties of type decimal?.
Otherwise, we need a more complicated solution, with BindingFlags, and/or Attribute on every field/property involved, and so on.
public void Recalc()
{
var propertyInfos = GetType()
.GetProperties()
.Where(pInfo => pInfo.PropertyType.IsValueType);
var fieldInfos = GetType()
.GetFields()
.Where(fInfo => fInfo.FieldType.IsValueType);
//create a dictionary with all the old values
//obtained from the backing fields.
var oldValueDictionary = fieldInfos.ToDictionary(
fInfo => fInfo.Name,
fInfo => (decimal?)fInfo.GetValue(this));
//set all properties to null
foreach (var pInfo in propertyInfos)
pInfo.SetValue(this, null);
//call all the getters to calculate the new values
foreach (var pInfo in propertyInfos)
pInfo.GetValue(this);
//compare new field values with the old ones stored in the dictionary;
//if only one different is found, the if is entered.
if (fieldInfos.Any(fInfo =>
(decimal?)fInfo.GetValue(this) != oldValueDictionary[fInfo.Name]))
{
//do stuffs
}
}
As a final note, your class configuration is very strange. Are you sure that setting all the calculations in the getters is the best choice? Maybe you should re-think about you design. One task is to retrieve a property value (a getter), another task is to calculate something (starting from some value stored in the backing fields)...

Javascript's void in C#?

Is there something like Javascript's void operator in C#?
Javascript's void, "evaluates an expression and discards the result, returning undefined". Thus, I'm looking for something built-in that "evaluates" and returns null, or maybe the type default. (So it should sort of be like the inverse of the null-coalescing ?? operator.)
Example use:
Person a;
public void main() {
var x = void(a = new Person());
// x should contain null
}
class Person { }
(Example does not compile due to illegitimate use of keyword "void", naturally.)
I currently use this—which works—but feels crufty:
protected object voided(object ob) {
return null;
}
Edit. Ok, so I definitely need to add some more details. I'm using the code in an inline DataBind expression in ASP.NET code. E.g.:
<asp:Repeater runat="server">
<ItemTemplate>
</tr><%# voided(globalPersonVariable = (Person)Container.DataItem)) %></tr>
</ItemTemplate>
</asp:Repeater>
Using default, unfortunately does not work here.
(I didn't include this additional information the first time, because I wanted to keep it a "pure" C#-question, not ASP.NET.)
Something like this you're looking for?
var x = default(Person) // null
var i = default(int) // 0
You could just make an extension method, Voided()
public static object Voided<TType>(this TType tThis)
{
return null;
}
Then you can call it like so:
(globalPersonVariable = (Person)Container.DataItem)).Voided()
If you want to combine this with the default stuff other people have mentioned, it would change to:
public static TType Voided<TType>(this TType tThis)
{
return default(TType);
}
Not sure what void function does in javascript, but to get a default value of a type, use default keyword:
protected T voided<T>(T obj) {
return default(T);
}
You could use the default keyword:
http://msdn.microsoft.com/en-us/library/xwth0h0d(v=vs.80).aspx
I just want to throw these two snippets into the mix.
Both work, but they still feel more verbose than necessary.
(globalPersonVariable = (Person)(Container.DataItem)) == null ? null : null
((Func<object,object>)(x => null))(globalPersonVariable = (Person)(Container.DataItem))
For databinding purposes, you can also emit the empty string:
(globalPersonVariable = (Person)(Container.DataItem)) == null ? "" : ""
The distinction might seem trivial, but this can save you from needing to cast
the nulls in certain situations.

Is there a better way to do this: Convert.IsDBNull(row[somecolumn]) checking

Is there a better way to write this code..
MyObject pymt = new MyObject();
pymt.xcol1id= Convert.IsDBNull(row["col1id"]) ? 0 : (int)row["col1id"];
pymt.xcold2id= Convert.IsDBNull(row["col2id"]) ? String.Empty : (string)row["col2id"];
pymt.xcold3id = Convert.IsDBNull(row["CustNum"]) ? 0 : (decimal)row["xcold3id"];
could this be done in a cleaner way .. like generic methods etc??
You could make generic extension methods like this:
public static class DataRowExtensions {
public static T GetValueOrDefault<T>(this DataRow row, string key) {
return row.GetValueOrDefault(key, default(T));
}
public static T GetValueOrDefault<T>(this DataRow row, string key, T defaultValue) {
if (row.IsNull(key)) {
return defaultValue;
} else {
return (T)row[key];
}
}
}
Usage:
MyObject pymt = new MyObject();
pymt.xcol1id = row.GetValueOrDefault<int>("col1id");
pymt.xcold2id = row.GetValueOrDefault<string>("col2id", String.Empty);
pymt.xcold3id = row.GetValueOrDefault<int>("CustNum"]);
Absolutely there's a cleaner way to write that code if you're using .NET 3.5, and without re-inventing extension methods that Microsoft already wrote for you. Just add a reference to System.Data.DataSetExtensions.dll, and you'll be able to do this:
MyObject pymt = new MyObject
{
xcol1id = row.Field<int?>("col1id") ?? 0,
xcol2id = row.Field<string>("col2id") ?? String.Empty,
xcol3id = row.Field<decimal?>("col3id") ?? 0M
};
I tend to use the null coalescing operator in situations like those. Also, DBNull.ToString returns string.Empty, so you don't have to do anything fancy there.
MyObject pymt = new MyObject();
pymt.xcol1id= row["col1id"] as int? ?? 0;
pymt.xcold2id= row["col2id"].ToString();
pymt.xcold3id = row["CustNum"] as decimal? ?? 0;
Better yet, add it as an extension method to the DataRow:
static T GetValueOrDefault<T>(this DataRow row, string columnName)
{
if (!row.IsNull(columnName))
{
// Might want to support type conversion using Convert.ChangeType().
return (T)row[columnName]
}
return default(T);
}
You can use it like:
pymt.xcol1id = row.GetValueOrDefault<int>("col1id");
pymt.xcol2id = row.GetValueOrDefault<string>("col2id");
pymt.xcol3id = row.GetValueOrDefault<decimal>("col3id");
static ToType GenericConvert<ToType>(object value)
{
ToType convValue = default(ToType);
if (!Convert.IsDBNull(value))
convValue = (ToType)value;
return convValue;
}
MyObject pymt = new MyObject();
pymt.xcol1id= GenericConvert<int>(row["col1id"]);
pymt.xcold2id= GenericConvert<string>(row["col2id"]) ?? String.Empty;
pymt.xcold3id = GenericConvert<decimal>(row["CustNum"]);
I actually like that. Our team had been using if/else statements which are more difficult to read in my opinion.
if (row["col1id"] == dbnull.value)
pymt.xcol1id = 0;
else
pymt.xcol1id = (int)row["col1id"];
Your code is easier to read because it places each assignment on individual lines.
A function as suggested by Stan might make the lines shorter but it hides the fact that nulls are being replaced unless you give it a very verbose name.
Some alternatives I can quickly think of:
Strongly typed datasets
Use the SqlTypes readers like ReadSqlInt32 since they all implement INullable.
Generate the code with XSLT transformation from XML, so the checking code is easy to change and maintain.

Categories