I'm getting these warnings from CodeContracts:
Array access might be above the upper bound. Did you meant 0 instead of 1?
Array access might be above the upper bound. Did you meant 1 instead of 2?
Array access might be above the upper bound. Did you meant 2 instead of 3?
Array access might be above the upper bound. Did you meant 3 instead of 4?
On this line of code:
private readonly string[] _addr;
public string AddressLine1
{
get
{
return _addr[0] ?? _addr[1] ?? _addr[2] ?? _addr[3];
}
}
public string AddressLine2
{
get
{
return _addr[1] ?? _addr[2] ?? _addr[3];
}
}
public string AddressLine3
{
get
{
return _addr[2] ?? _addr[3];
}
}
How do I tell the Contracts analyzer that these indices are guaranteed inside bounds? _addr is initialized in the constructor to string[4].
I was able to get rid of these warnings by adding a method to that class that defined the invariants:
[ContractInvariantMethod]
private void AddressInvariants()
{
Contract.Invariant(_addr.Length == 4);
}
However, I think there's also a bug in your code.
If _addr[0] == null and _addr[1] != null, then AddressLine1 and AddressLine2 return the same value. This seems like a bug.
You can fix this easily enough (and remove the need to specify contract invariants) by using something along the lines of what #ryanyuyu mentioned:
public string AddressLine1
{
get
{
// Use the first non-null element.
return _addr.Where(x => x != null).FirstOrDefault();
}
}
public string AddressLine2
{
get
{
// Use the second non-null element.
return _addr.Where(x => x != null).Skip(1).FirstOrDefault();
}
}
public string AddressLine3
{
get
{
// Use the third non-null element.
return _addr.Where(x => x != null).Skip(2).FirstOrDefault();
}
}
ContractInvariantMethod works when _addr is a class member. But Contract.Assert() works with local variables too.
static void MyParse(string foo)
{
string[] split = foo.Split(',');
Contract.Assert(split.Length == 4);
string a = split[0];
string b = split[1];
string c = split[2];
string d = split[3];
}
I don't know about the Contracts analyzer, but your code could be cleaner. You are basically repeating code that just finds the first non-null string (and if the last element is null, you are returning that regardless). I'm a fan of using LINQ .FirstOrDefault which will let you find the first element that matches a condition (in your case not null). If no such element is found, it returns the default value (for a String it's null)
return _addr.FirstOrDefault(str => str != null);
See it in action at this .NET Fiddle.
Related
Let's say I have a model class that looks like this:
public class ModelTest {
public string val1 {get;set;}
public string val2 {get;set;}
public string val3 {get;set;}
}
Somewhere in my code this ModelTest gets its data. The caveat is that, only 1 of them will hold a value
var model = new ModelTest() {val1=null, val2="value", val3=null} //Sudo code
What I am trying to do somehow, is compare a value to whichever 1 of the 3 items can potentially have a values, so something like:
var testCompare = "someValue"
if (testCompare == model. ....//how can I get the NOT NULL value from ModelTest here for comparison
While your data model isn't ideal, it is possible to check each of the properties by utilizing the || operator to compare each value. As long as your testCompare variable does not contain null, you can also omit a null check.
if (model.val1 == testCompare ||
model.val2 == testCompare ||
model.val3 == testCompare)
{ }
As mentioned in the comments, if you want a more succinct version, you can use the null coalescing operator, ??, to check subsequent properties if your prior property returns null. At the end of the null coalescing chain, the first non-null property will be compared to your testCompare string. Note that you must wrap all three properties in parentheses and that this has different behavior; it only tests the first non-null property whereas the previous version tests ALL properties for a match.
if (testCompare == (model.val1 ?? model.val2 ?? model.val3))
{
}
You could add a property to your ModelTest class that provides the first non-null value (if any) in your object:
public class ModelTest
{
public string val1 { get; set; }
public string val2 { get; set; }
public string val3 { get; set; }
public string val => val1 ?? val2 ?? val3;
}
and then check against that:
if (model.val == testCompare) { }
You could probably create a method (or even property) like:
public string Val()
{
if (val1 != null) return val1;
if (val2 != null) return val2;
if (val3 != null) return val3;
return null;
}
There is probably a shorter way to write this code. Also, if two or more of the values are not null, then it will return the first one.
It's a very bizarre use case, but let's go with it. Here's another option for the bonfire..
public class ModelTest {
private string _val;
public string val1 {get => _val; set => _val ??= value;}
public string val2 {get => _val; set => _val ??= value;}
public string val3 {get => _val; set => _val ??= value;}
}
Whichever one of these is set to non null ends up committing that value to _val - ??= writes the right hand into the left hand only if the left hand is null, essentially like left = left ?? right.
It doesn't matter which you use to access the value..
Note that there is only one data storage location so this approach is incapable of remembering two values, or which value was the non null. You wouldn't use this for disparate properties like name, address and social security number because it could lead to bizarre effects elsewhere. This is for a very narrow use case of "there are three properties that are essentially the same thing, they cannot be collapsed to one, and I don't know which one will be set but i can treat them equivalent for reading"
You can override the method 'Equals' of ModelTest class however you like. Example:
public class ModelTest {
public string val1 {get;set;}
public string val2 {get;set;}
public string val3 {get;set;}
public override bool Equals(object obj)
{
if(!typeof(string).IsInstanceOfType(obj))
return base.Equals(obj);
string value = obj as string;
if (val1.Equals(value))
return true;
if (val2.Equals(value))
return true;
if (val3.Equals(value))
return true;
return false;
}
}
For to use the method:
if(model.Equals("yourValue"))
...
What about solution which contains combination of reflection and Linq,
Test Data
var model = new ModelTest() {val1=null, val2="value", val3=null} ;
Usage
var result =
model.GetType()
.GetProperties()
.FirstOrDefault(prop => prop.GetValue(model, null) != null);
Print result
Console.WriteLine(result.GetValue(model));
This is my first attempt with reflection, suggestions are most welcome
.Net fiddle
Note: This is just an alternate solution, less performant. If you are looking for elegant solution, then kindly try other solutions.
I declare a variable like this:
public static int aBtn;
But the only valid values are 0,1,2,3,4 and 5
Is there any way that I can avoid any problems with my code later on my limiting it so that something like an exception will happen if I try to set the value to 6.
Note that I still want to be able to do things like:
aBtn = aBtn + 1;
No. This is a good example of why exposing public fields is a bad idea - you have no control over how they're used.
If you change it into a property, you can validate the value in the setter:
// TODO: Use a better name than either foo or aBtn
private static int foo;
public static int Foo
{
get => foo;
set => foo = value >= 0 && value < 6
? value
: throw new ArgumentOutOfRangeException("Some useful error message here");
}
If you don't like using the conditional ?: operator there, you can use a block-bodied setter:
public static int Foo
{
get => foo;
set
{
if (value < 0 || value > 5)
{
throw new ArgumentOutOfRangeException("Some useful error message");
}
foo = value;
}
}
Or better, have a utilty method that validates a value and returns the input if it's in range, or throws an exception otherwise. You can then use something like:
public static int Foo
{
get => foo;
set => foo = Preconditions.CheckArgumentRange(nameof(value), value, 0, 5);
}
Here's a slightly modified version of CheckArgumentRange from Noda Time. (The real version has a separate method to do the throwing, which I suspect is for performance reasons, to allow the comparison part to be inlined.)
internal static int CheckArgumentRange(
string paramName, int value, int minInclusive, int maxInclusive)
{
if (value < minInclusive || value > maxInclusive)
{
throw new ArgumentOutOfRangeException(paramName, value,
$"Value should be in range [{minInclusive}-{maxInclusive}]");
}
return value;
}
Couldn't you just use an enum with your only possible values? It's a good way to define small categorical sets.
For example:
public enum RangedInt
{
cero,
one,
two,
three,
four,
five,
six = 6
}
public class MyClass
{
public RangedInt Field { get; set; }
}
Sure. Use an auxiliary variable to test for the values you wish, then, if the tests go OK, pass the value to the real variable.
I think this idea is better expressed through a code. Modify it according to your wishes:
private static int aBtn;
public static int aBtnTest
{
get
{
return aBtn;
}
set
{
if ((value<0)||(value>6))) //here you test for the values you want
//do something
}
}
When you want to use your variable, you do all the processing using aBtnTest, not aBtn. By doing so, all the comparisons are made automatically by the compiler and you do not have to worry anymore about it.
I'm working in JetBrains Rider and have ran into a warning that keeps appearing. Consider this situation:
public enum ValueEnum {
A,B,C
}
public class Value {
public ValueEnum ValueEnum { get; set; }
}
public class ValueWrapper {
public IEnumerable<Value> Values { get; set; }
}
I'm trying to obtain the first enum in the list and convert it into a string. This code works fine:
var format = string.Empty;
if (alert.Values != null && alert.Values.Count > 0)
{
var template = alert.Values.First();
format = nameof(template.ValueEnum);
}
However I'm getting the Value assigned is not used in any execution path warning. Converting the above snippet into the following:
var format2 = string.Empty;
if (alert.Values != null)
{
foreach (var template in alert.Values)
{
format2 = nameof(template.ValueEnum);
break;
}
}
Yields a Local variable "template" is only used to capture its name.
Is there a cleaner way to write this (using LINQ or whatnot) to be in line with c# best practices?
Assuming you actually want the string value of the enum, and not the literal string "ValueEnum", try:
alert.Values?.FirstOrDefault()?.ValueEnum.ToString() ?? string.Empty;
(Both of your approaches would have worked, had you changed nameof(template.ValueEnum) to template.ValueEnum.ToString(), but they are unnecessarily verbose).
I have a class like this :
public class Test
{
public string STR1{ get; set; }
public INT INT1{ get; set; }
public DOUBLE DBL1{ get; set; }
public DATETIME DT1{ get; set; }
}
Normally, before saving the object, i will have to check all the properties inside this Class, and return a warning message if there is any empty/null property. There is easy way to do this by simply check each property like this :
if (string.IsNullOrEmpty(t.STR1))
return "STR1 is empty"
if (t.INT1 == 0)
return "INT1 = 0";
if (t.DBL1 == 0)
return "DBL1 = 0";
if (t.DT1 == DateTime.MinValue)
return "DT1 is empty"
But what if my class has more properties, actually it contains about 42 properties now, and still growing up. So i was thinking for a "cleaner" way to perform this check, and i found this topic which is quiet similar to my issue : Reflection (?) - Check for null or empty for each property/field in a class?
But this solution does not meet my need as i have to list the values that = null/empty string/0/DateTime.MinValue
Believe me, i wanted to post my "tried code" but i can't figure out a sensible LINQ query for this task (i'm a novice in C#)
Any help is greatly appreciated !
Since you need to test objects of different types, you can combine the solution from the linked question with use of dynamic to dispatch to the proper method.
First, define an overloaded method for each type.
private static IsEmpty(string s) { return string.IsNullOrEmpty(s); }
private static IsEmpty(double f) { return f == 0.0; }
private static IsEmpty(int i) { return i == 0; }
private static IsEmpty(DateTime d) { return d == DateTime.MinValue; }
Now you can use these methods in your check:
List<string> emptyProperties = typeof(MyType).GetProperties()
.Select(prop => new { Prop = prop, Val = prop.GetValue(obj, null) } )
.Where(val => IsEmpty((dynamic)val.Val) // <<== The "magic" is here
.Select(val => val.Prop.Name)
.ToList();
The tricky part of the code casts the value to dynamic, and then tells the runtime to find the most appropriate IsEmpty method for it. The downside to this approach is that the compiler has no way of telling whether the method is going to be found or not, so you may get exceptions at runtime for properties of unexpected type.
You can prevent these failures by adding a catch-all method taking object, like this:
private static IsEmpty(object o) { return o == null; }
What is the easiest way to take an objects and convert any of its values from null to string.empty ?
I was thinking about a routine that I can pass in any object, but I am not sure how to loop through all the values.
When your object exposes it's values via properties you can write something like:
string Value { get { return m_Value ?? string.Empty; } }
Another solution is to use reflection. This code will check properties of type string:
var myObject = new MyObject();
foreach( var propertyInfo in myObject.GetType().GetProperties() )
{
if(propertyInfo.PropertyType == typeof(string))
{
if( propertyInfo.GetValue( myObject, null ) == null )
{
propertyInfo.SetValue( myObject, string.Empty, null );
}
}
}
Using reflection, you could something similar to :
public static class Extensions
{
public static void Awesome<T>(this T myObject) where T : class
{
PropertyInfo[] properties = typeof(T).GetProperties();
foreach(var info in properties)
{
// if a string and null, set to String.Empty
if(info.PropertyType == typeof(string) &&
info.GetValue(myObject, null) == null)
{
info.SetValue(myObject, String.Empty, null);
}
}
}
}
Presumably, you have a report or a form somewhere showing "null" all over the place, instead of a nice, pleasant "".
It's best to leave the nulls as they are, and modify your display code wherever appropriate. Thus, a line like this:
label1.Text = someObject.ToString();
should become:
if (someObject == null)
{
label1.Text = ""; // or String.Empty, if you're one of *those* people
}
else
{
label1.Text = someObject.ToString();
}
and you can functionalize it as necessary:
public void DisplayObject(Label label, Object someObject)
{
if (someObject == null)
{
label.Text = ""; // or String.Empty, if you're one of *those* people
}
else
{
label.Text = someObject.ToString();
}
}
You could use reflection. Here's an example with one level of nesting:
class Foo
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo
{
Prop1 = (string)null,
Prop2 = (string)null,
Prop3 = (string)null,
};
var props = typeof(Foo).GetProperties()
.Where(x => x.PropertyType == typeof(string));
foreach (var p in props)
{
p.SetValue(foo, string.Empty, null);
}
}
}
You can do that via reflection without too much trouble, and I am sure that by the time I post this there will be answers that tell you exactly how to do that.
But I personally don't like the reflection option.
I prefer to maintain object invariants for all of the object's members through a variety of means. For string members, the invariant is often that it not be null, and sometimes there are maximum length requirements as well (for storage in a database, for example). Other members have other sorts of invariants.
The first step is to create a method that checks all the invariants that you define for the object.
[Conditional("DEBUG")]
private void CheckObjectInvariant()
{
Debug.Assert(name != null);
Debug.Assert(name.Length <= nameMaxLength);
...
}
Then you call this after any method that manipulates the object in any way. Since it is decorated with the ConditionalAttribute, none of these calls will appear in the release version of the application.
Then you just have to make sure that none of the code allows any violations of these invariants. This means that the string fields need to have either initializers in their declarations or they need to be set in all the constructors for the object.
A special problem, and the one that probably motivated this question, is what to do about automatic properties.
public string Name { get; set; }
Obviously, this can be set to null at any time, and there's nothing you can do about that.
There are two options with regard to automatic properties. First, you can just not use them at all. This avoids the problem entirely. Second, you can just allow any possible string value. That is, any code that uses that property has to expect nulls, 10 mb strings or anything in between.
Even if you go with the reflection option to remove nulls, you still have to know when to call the magic-null-removal method on the object to avoid NullReferenceExceptions, so you haven't really bought anything that way.
+1 to Tanascius's answer. I used this answer but tweaked it a bit.
First I only grab the properties that are strings, so it doesn't loop through all my properties. Secondly, I placed in it my BaseEntity class that all my entities inherit from, which makes it global, so I don't have to put it on all my Entities.
public class BaseEntity
{
public int Id { get; set; }
public BaseEntity()
{
var stringProperties = this.GetType().GetProperties().Where(x => x.PropertyType == typeof(string));
foreach (var property in stringProperties)
{
if (property.GetValue(this, null) == null)
{
property.SetValue(this, string.Empty, null);
}
}
}
}