Any way to avoid boxing/unboxing inside linq - c#

I am trying to write a Linq expression which checks whether any element in the List of objects matches with the predicate.
protected override void ValidateRulesBeforeDelete(List<object> deleteRecords)
{
base.ValidateRulesBeforeDelete(deleteRecords);
var defaultProductStatus = GetDefaultProductStatus();
if (deleteRecords.Any(x => x.Equals(defaultProductStatus.Id)))
{
throw new CustomException(PageResource.ProductStatusViewModel_CannotDeleteDefaultProduct);
}
}
public class ProductStatusViewModel
{
public int Id { get; set; }
}
The above code is working fine. But, recently I read about boxing/unboxing in CLR Via C# and my doubt is, to apply above predicate will the compiler box integer to object for each element in the list??
I am 100% sure all the time the list contains integers boxed as object.
So is there any way I can re-write the above code to avoid boxing/unboxing if there are happening any?.

Related

More informative comparison of objects in C#

In my C# testing, I often want to compare two objects of the same type (typically an expected object against the actual object), but I want to allow for some flexibility. For example, there may be timestamp fields that I know can't be equal or some fields that I just want to ignore when comparing the objects.
Most importantly, I want to provide an informative message that describes where the two object properties' values differ in order that I can quickly identify what the problem is. For example, a message that says "Source property Name value Fred does not match target property Name value Freda".
The standard Equals and Comparer methods just seem to return ints or Booleans which don't provide enough information for me. At the moment, my object comparison methods return a custom type that has two fields (a boolean and a message), but my thinking is that there must be a more standard way to do this. These days, perhaps a Tuple might be the way to go, but I would welcome suggestions.
"Comparison" might not be the word for what you're trying to do. That word already has a common meaning in this context. We compare objects for equality, which returns a boolean - they are equal or they are not. Or we compare them to see which is greater. That returns an int which can indicate that one or the other is greater, or that they are equal. This is helpful when sorting objects.
What you're trying to do is determine specific differences between objects. I wouldn't try to write something generic that handles different types of objects unless you intend for them to be extremely simple. That gets really complicated as you get into properties that return additional complex objects or collections or collections of complex objects. It's not impossible, just rarely worth the effort compared to just writing a method that compares the particular type you want to compare.
Here's a few interfaces and classes that could make the task a little easier and more consistent. But to be honest it's hard to tell what to do with this. And again, it gets complicated if you're dealing with nested complex properties. What happens if two properties both contain lists of some other object, and all the items in those lists are the same except one on each side that have a differing property. Or what if they're all different? In that case how would you describe the "inequality" of the parent objects? It might be useful to know that they are or are not equal, but less so to somehow describe the difference.
public interface IInstanceComparer<T>
{
IEnumerable<PropertyDifference> GetDifferences(T left, T right);
}
public abstract class InstanceComparer<T> : IInstanceComparer<T>
{
public IEnumerable<PropertyDifference> GetDifferences(T left, T right)
{
var result = new List<PropertyDifference>();
PopulateDifferences(left, right, result);
return result;
}
public abstract void PopulateDifferences(T left, T right,
List<PropertyDifference> differences);
}
public class PropertyDifference
{
public PropertyDifference(string propertyName, string leftValue,
string rightValue)
{
PropertyName = propertyName;
LeftValue = leftValue;
RightValue = rightValue;
}
public string PropertyName { get; }
public string LeftValue { get; }
public string RightValue { get; }
}
public class Animal
{
public string Name { get; }
public int NumberOfLimbs { get; }
public DateTime Created { get; }
}
public class AnimalDifferenceComparer : InstanceComparer<Animal>
{
public override void PopulateDifferences(Animal left, Animal right,
List<PropertyDifference> differences)
{
if(left.Name != right.Name)
differences.Add(new PropertyDifference("Name", left.Name, right.Name));
if(left.NumberOfLimbs!=right.NumberOfLimbs)
differences.Add(new PropertyDifference("NumberOfLimbs",
left.NumberOfLimbs.ToString(),
right.NumberOfLimbs.ToString()));
}
}
You could use extension methods to do this. For example:
public static Extensions
{
public static void CompareWithExpected(this <type> value, <type> expected)
{
Assert.AreEqual(expected.Property1, value.Property1, "Property1 did not match expected";
Assert.AreEqual(expected.Property2, value.Property2, "Property2 did not match expected";
}
}
Then this can be used as follows:
public void TestMethod()
{
// Arrange
...
// Act
...
// Assert
value.CompareWithExpected(expected);
}
You could have any number of these extension methods allowing you the flexibility to check only certain values etc.
This also means you do not need to pollute your types with what is essentially test code.

Code brevity in C# - condensing a setter that throws if null

In prior versions of C#, if you wanted to prevent a null reference exception, you needed to build your setters defensively:
public Guid ItemId { get; set; } //foreign key, required
private Item _item;
public virtual Item Item {
get {
return _item;
}
set {
if(value == null) throw new ArgumentNullException(nameof(value));
_item = value;
ItemId = value.ItemId;
}
}
With more modern implementations, this can be condensed a certain amount using the null-coalescing operator and expression bodies:
private Item _item;
public virtual Item Item {
get => _item;
set => _item = value ?? throw new ArgumentNullException(nameof(value));
}
However, I am curious if this could not be condensed entirely down into a variation of the standard reference:
public virtual Item Item { get; set; }
Such that you do not have to define a private item.
Suggestions? Or is the second code block as efficient/simple as I can get?
I am looking for a solution within the current C# framework, not something I have to spend money on. Right now my use case proposition does not support a paid product
Disclaimer: Those are potential 'alternative' ways of filtering out invalid assignments into properties. This might not provide a straight answer to the question, but rather give ideas how to go on about doing it more generically without defining private properties and defining getters and setters explicitly.
Depending on what Item actually is, you could perhaps create a non-nullable type of Item by creating it as a struct.
Non nullable types are called structs. They are nothing new, they are value types which allow to store properties of type int, string, bool etc.
As on MSDN:
A struct type is a value type that is typically used to encapsulate
small groups of related variables, such as the coordinates of a
rectangle or the characteristics of an item in an inventory.
The following example shows a simple struct declaration:
public struct Book
{
public decimal price{ get; set;}
public string title;
public string author;
}
Reference
Edit (Struct should be sufficient if the object is supposed to be non-nullable type, however if we're talking properties of the class then read below.) :
Another way would be using OnPropertyChanged event which is part of the INotifyPropertyChanged interface.
While the event does not explicitly give you the value that has been changed to, you can grab it as it does provide you the property name. So you could run your validation post assignment and throw then, I suppose however it might not be the best option.
void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var propertyValue = sender.GetType().GetProperty(e.PropertyName).GetValue(sender);
}
Another solution would be using DataAnnotations and add Required attributes on your properties. If I'm not mistaken they will not throw straight away, until you call your own validate function to validate the class, I guess, combined with the above method this would work pretty well and would be pretty generic. Once written you wouldn't have to write your getters and setters explicitly but rather attach just one event to your class and validate it once a property changes.
Here's a small example:
Your Item model for example...
public class Item
{
[Required]
public string Name { get; set; }
}
You would then implement a generic function which would validate all properties.
public bool TryValidate(object #object, out ICollection < ValidationResult > results) {
var context = new ValidationContext(#object, serviceProvider: null, items: null);
results = new List <ValidationResult> ();
return Validator.TryValidateObject(
#object, context, results,
validateAllProperties: true
);
}
Inside that function you would of course throw an exception if validation failed, your results array would contain properties that it failed on an default messages if I'm not mistaken. I believe this is a bit complex, but if you're looking for reducing the number of properties and setter implementations, this could be a step forward. I'm not sure on the overhead etc. Personally, I think on a larger scale, this would be super useful to validate models which are created on the fly from db data or any external source.
Validator Reference | Data Annotations Reference | ValidationResults Reference | PropertyChanged MSDN Sample

Finding an item in a List<T>

I have the follow example:
public class Commands
{
public int ID { get; set; }
public List<string> Alias { get; set; }
}
public class UserAccess
{
public int AccessID { get; set; }
// other stuff not needed for the question
public List<Commands> AllowedCommands { get; set; }
}
Now I wanted to implement on the UserAccess a way to return the command ID or NULL if no Alias were found on the list, see a dirty example of what I am saying below HasCommand:
public class UserAccess
{
public ID { get; set; }
// other stuff not needed for the question
public List<Commands> AllowedCommands { get; set; }
public Commands HasCommand(string cmd)
{
foreach (Commands item in this.AllowedCommands)
{
if (item.Alias.Find(x => string.Equals(x, cmd, StringComparison.OrdinalIgnoreCase)) != null)
return item;
}
return null;
}
}
My question is what would be the most efficient way to run or implement the HasCommand method ?
Or is there a better way to implement it into the UserAccess ?
Can be shortened a little bit
public Commands HasCommand(string cmd)
{
return AllowedCommands.FirstOrDefault(c => c.Alias.Contains(cmd, StringComparer.OrdinalIgnoreCase));
}
but it's pretty much the same thing.
public Commands HasCommand(string cmd)
{
return this.AllowedCommands.FirstOrDefault(item => item.Alias.Find(x => string.Equals(x, cmd, StringComparison.OrdinalIgnoreCase)) != null);
}
You do not need to use Where + FirstOrDefault. The FirstOfDefault can have condition.
Also, 3 suggestions for further improvement:
(1) I would encourage the use of IEnumerable instead of List, if possible.
(2) I would call "Commands" just "Command".
(3) I would make all commands be able to be easily referenced via a class like this:
public class Command {
public Command(int id, IEnumerable<string> aliases) {
Id = id;
Aliases = alias;
}
public int Id { get; set; }
public IEnumerable<string> Aliases { get; set; }
}
public class Commands {
public static readonly Command CommandNameHere1(yourIdHere1, yourAliasesHere1);
public static readonly Command CommandNameHere2(yourIdHere2, yourAliasesHere2);
//etc.
}
Assuming that by "efficient", you mean fast, anytime you are looking up a string in a collection of strings, and that collection is likely to contain more than a few entries, you should always use a hash lookup. Doing a simple scan of the list takes exponential time as the count of items goes up, while the count has little effect on a hash lookup. In .NET, this has traditionally been handled by the Dictionary class, which is commonly used to index a collection of objects with a key (which is often a string). However, the value can't be null, and this led to passing the same string in as both the key and value - rather ugly. Finally, .NET 4 provided HashSet, which you should use for such a case of only having a key and no value.
In your case, you have the (not uncommon) situation of needing a case-insensitive compare. The common solution for this is to lower-case the string keys when adding them to the dictionary (or HashSet). This tiny overhead on add is vastly outweighed by the savings on lookups, since all programmers should know and understand that case-insensitive compares are vastly slower than case-sensitive, especially with Unicode - the CPU can't just do a block compare of data, but must check each pair of characters specially (even using a table look-up, this is vastly slower).
If your Alias names can be in lower case, change them from List to HashSet. If not, use Dictionary where the key is added as lower case, and the value is the (mixed-case) Alias string. Assuming the use of Dictionary, your code would become:
public Commands HasCommand(string cmd)
{
foreach (Commands item in AllowedCommands)
{
if (item.Alias.ContainsKey(cmd))
return item;
}
return null;
}
Finally, also on the subject of performance, using LINQ is almost always going to result in slower performance - somewhere between a little slower and a lot slower, depending upon the situation. It does make nice, compact source for simple things, and I use it quite a bit myself, but if you're certain that performance is an issue for a piece of a code, you probably shouldn't use it (unless it's PLINQ, of course).
So, if you want as few lines of code as possible, use the other answer posted here. If you want speed, use mine.
It almost goes without saying, but when you're worried about the performance of some small chunk of code like this, just wrap it in a for loop and repeat it until it takes 5-10 seconds to execute - just add orders of magnitude as needed, whether it's 1,000 or 1,000,000 reps, and time it with System.Diagnostics.Stopwatch. Try alternative logic, and repeat the test. The 5-10 seconds is a minimum designed to mask the fluctuations caused by a managed environment and other stuff executing on the same machine (you should obviously also avoid running other apps during the test). Of course, for overall performance testing of a complicated application, a performance analyzer tool would be recommended.

Quick Question: C# Linq "Single" statement vs "for" loop

I need some clarification. Are these two methods the same or different? I get a little bit confused about when the reference to an object passed in a parameter by value is updated and when a new one is created. I know if that assignment creates a new reference, but what about changing a property? Will both of these methods update the field "_someObjectList" the same way?
public class SomeObject{
public Guid UniqueKey { get; set; }
public object SomeProperty{ get; set; }
}
public class SomeObjectListWrapper{
public SomeObjectListWrapper(List<SomeObject> someObjectList){
_someObjectList = someObjectList;
}
private readonly List<SomeObject> _someObjectList;
public void ReplaceItemPropertyValue1(Guid itemUniqueKey, object propertyValue)
{
List<int> resultIndices = new List<int>();
for (var i = 0; i < _someObjectList.Count(); i++)
{
if (_someObjectList[i].UniqueKey == itemUniqueKey)
resultIndices.Add(i);
}
if (resultIndices.Count != 1)
throw new Exception(
"just pretend this is the same exception as Single() throws when it can't find anything");
_someObjectList[resultIndices[0]].SomeProperty = propertyValue;
}
public void ReplaceItemPropertyValue2(Guid itemUniqueKey, object propertyValue)
{
_someObjectList.Single(x=>x.UniqueKey==itemUniqueKey).SomeProperty=propertyValue;
}
}
Because SomeObject is a class (ie. a reference type), both ReplaceItemPropertyValue methods are updating the same object as was inserted into the list and will be retrieved from the list later. (If SomeObject was a struct/value type, the compiler would prevent you from updating an rvalue/return value [1].)
As a minor side-note, your two methods are not actually identical. The Single method raises an exception if there is more than one matching item in the sequence. To properly match the behaviour, use First instead.
"rvalue" is not actually short for "return value," it just happens that in this case your rvalue is a return value, which is why I specified both options.
They may do the same thing depending on the data in your list.
ReplaceItemPropertyValue2 uses the Single method which will throw an exception if itemUnqiueKey is not found or found more than once.
But as long as itemUniqueKey can't appear more than once in the list, the two functions should accomplish the same task.
Both may be same.
The algorithm in the for loop set the object when key matches and then breaks out.
While the LINQ statement will set the object to all entries whose key match. It depends if your collection has same key entered more than once.

Property as parameter? C#

So I've got a whole bunch of options, every different page/tab can have their own local options. We'll have maybe 10-15 pages tabs open tops. I need to implement a way to show the global defaults, weather the all the tabs have consistent values. I'm working on the model/viewmodel portion of a WPF app.
I'd love to find a way that is more elegant since I'm having to cut and past roughly the same code 20+ times and just change property names. Maybe this is the problem Dynamics solve, but right now this feels both wrong and painful.
Here is an example of my current solution:
public class Foo
{
private bool fooVar1;
private bool fooVar2;
//lots of these
private decimal fooVar23;
public Foo()
{
}
public bool FooVar1
{
get;
set;
}
//you get the picture...
}
public class FooMonitor
{
private Foo defaultFoo;
private List<Foo> allFoos;
public FooMonitor(Foo DefaultFoo)
{
defaultFoo = DefaultFoo;
}
public void AddFoo(Foo newFoo)
{
allFoos.Add(newFoo);
}
public void AddFoo(Foo oldFoo)
{
allFoos.Remove(oldFoo);
}
public bool IsFooVar1Consistent
{
get
{
Foo[] tempFoos = allFoos.ToArray();
foreach (Foo tempFoo in tempFoos)
{
if (tempFoo.FooVar1 != defaultFoo.FooVar1) return false;
}
return true;
}
}
}
Or am I approaching this problem entirely incorrectly.
As I'm writing this question (After about 2000 lines of code) I'm thinking of how I read that WPF itself implements Dictionary look ups that crawl up to the parent to see if a Property is present and what the value should be.
Well, for a start you are defining both backing fields which will never be used and automatic properties. This is enough for a simple bool property:
public bool FooVar1 { get; set; }
No need for the private field. This greatly reduces the number of lines in your example.
I'd love to find a way that is more
elegant since I'm having to cut and
past roughly the same code 20+ times
and just change property names.
Code generators exist for exactly this purpose. But if you don't want to go that route, you can shorten your code to this:
return allFoos.All(foo => foo.FooVar1 == defaultFoo.FooVar1);
I'm not quite sure what the question is, but if you're looking for some way to unify the IsFoorVarXConsistent code, you could do it using reflection or by passing in an expression:
public bool IsConsistent(Func<Foo, bool> property)
{
foreach (Foo tempFoo in allFoos)
{
if (property(tempFoo) != property(defaultFoo))
return false;
}
return true;
}
Called like this:
bool is1Consistent = IsConsistent(f => f.FooVar1);
As shown this will only work for boolean properties. To extend it to other types, we can make it generic in the property type. However, in this case we cannot use != to test for inequality because not all types define a != operator. Instead we can use the .Equals method and the ! operator:
public bool IsConsistent<T>(Func<Foo, T> property)
where T : struct
{
foreach (Foo tempFoo in allFoos)
{
if (!property(tempFoo).Equals(property(defaultFoo)))
return false;
}
return true;
}
The where T : struct clause restricts this to value types like int, bool and decimal. In particular it will not work on strings. Removing the where constraint allows it to work on strings and other reference types, but creates the possibility of property(tempFoo) being null, which would cause a NullReferenceException when we called .Equals on it. So if you remove the value types constraint then you will need to add error handling for this scenario.

Categories