Can anyone help?
I have some code that is shared between 2 projects. The code points to a model which basically is a collection of properties that comes from a db.
Problem being is that some properties use nullable types in 1 model and the other it doesn't
Really the dbs should use the same but they don't ..
so for example there is a property called IsAvailble which uses "bool" in one model and the other it uses bool? (nullable type)
so in my code i do the following
objContract.IsAvailble.Value ? "Yes" : "No" //notice the property .VALUE as its a bool? (nullable type)
but this line will fail on model that uses a standard "bool" (not nullable) as there is no property .VALUE on types that are NOT nullable
Is there some kind of helper class that i check if the property is a nullable type and i can return .Value .. otherwise i just return the property.
Anybody have a solution for this?
EDIT
This is what i have now..... i am checking HasValue in the nullable type version
public static class NullableExtensions
{
public static T GetValue(this T obj) where T : struct
{
return obj;
}
public static T GetValue(this Nullable obj) where T : struct
{
return obj.Value;
}
public static T GetValue<T>(this T obj, T defaultValue) where T : struct
{
return obj;
}
public static T GetValue<T>(this Nullable<T> obj, T defaultValue) where T : struct
{
if (obj.HasValue)
return obj.Value;
else
return defaultValue;
}
}
This is a little weird, but maybe you can use an extension method here:
static class NullableExtensions
{
public static T GetValue<T>(this T obj) where T : struct
{
return obj;
}
public static T GetValue<T>(this Nullable<T> obj) where T : struct
{
return obj.Value;
}
}
They will work with nullable or regular types:
int? i = 4;
int j = 5;
int a = i.GetValue();
int b = j.GetValue();
I wouldn't cast. use the ?? operator
http://msdn.microsoft.com/en-us/library/ms173224(VS.80).aspx
bool? isAvailble = null;
//string displayIsAvailble = (bool)(isAvailble) ? "Yes" : "No"; //exception Nullable object must have a value.
string displayIsAvailble = (isAvailble ?? false) ? "Yes" : "No"; //outputs "no"
Console.WriteLine(displayIsAvailble);
(bool)(objContract.IsAvailble) ? "Yes" : "No"
Best I can suggest is to always cast to the nullable, then use the null coalescing operator to say what you want the value to be when it's null. e.g.:
string s3 = (bool?)b ?? false ? "yes" : "no";
The above will work whether b is defined as bool or bool?
Convert.ToBoolean(objContract.IsAvailble) ? "yes" : "no"
OR
Is this what you are looking for?
bool? n = false;
bool nn = true;
Console.WriteLine(n ?? nn);
One more alternative:
objContract.IsAvailble == true ? "Yes" : "No"
On the nullable, only true is true, null or false is false. On the regular bool, true/false is normal.
You could use:
bool? b1 = objContract.IsAvailable;
string s1 = b1.Value ? "Yes" : "No";`
This should work whether objectContract.IsAvailable is a bool or bool? or any other nullable type.
For dates for example:
DateTime? t1 = objContract.EitherNullableOrNotNullableDate;
string s1 = t1.Value.ToString();
Related
Is there any difference between those two ways to write the same thing?
int? foo = GetValueOrDefault();
var obj = new
{
//some code...,
bar = foo.HasValue ? foo > 0 : (bool?)null
}
VS
int? foo = GetValueOrDefault();
var obj = new
{
//some code...,
bar = foo.HasValue ? foo > 0 : default(bool?)
}
It is the same. A Nullable<bool> is a struct and the language specification states:
The default value of a struct is the value produced by setting all
fields to their default value (ยง15.4.5).
Since a Nullable<T> has these two fields:
private bool hasValue; // default: false
internal T value; // default value of T, with bool=false
So yes, using default(bool?) has the same effect as using (bool?)null, because (bool?)null is also a Nullable<bool> with hasValue=false(same as using new Nullable<bool>()).
Why you can assign null at all to a Nullable<T> which is a struct, so a value type? Well, that is compiler magic which is not visible in the source.
I'm working with an enumeration and xml files.
Because xml always returns string-values, I need to convert these values to my enum-values.
//while reading the xml file:
ItemType = xml.Element("ItemType") != null ?(ProjectTreeItemTypes)Enum.Parse(typeof(ProjectTreeItemTypes), elem.Element("ItemType").Value,true) : ProjectTreeItemTypes.None
I'd like to implement something like the always avaialbel .toString() to my enumeration. Is there a way to solve this?
The result should look like this:
ItemType = xml.Element("ItemType") != null ? elem.Element("ItemType").Value.toItemType() : ProjectTreeItemTypes.None
Is this possible somehow or similar?
Evene something like simple cast would be nice:
ItemType = xml.Element("ItemType") != null ? (ProjectTreeItemTypes)elem.Element("ItemType").Value : ProjectTreeItemTypes.None
Thanks
You may write an extension method for that
public static class Ext
{
public static ProjectTreeItemTypes ToItemType(this string value)
{
return value == null
? ProjectTreeItemTypes.None
: (ProjectTreeItemTypes) Enum.Parse(typeof(ProjectTreeItemTypes), value, true);
}
}
It'll accept string, which is XElement.Value and return ProjectTreeItemTypes enum
The usage example
ItemType = xml.Element("ItemType")?.Value.ToItemType() ?? ProjectTreeItemTypes.None;
Since you can pass a null value to extension method, your null check can be simplified using null-conditional operator ?.
You can create an extension method in a static class.
public static class Extentsion
{
public static ProjectTreeItemTypes ToEnum(this XElement elem)
{
return elem.Element("ItemType") != null ?
(ProjectTreeItemTypes)Enum.Parse(typeof(ProjectTreeItemTypes), elem.Element("ItemType").Value,true) : ProjectTreeItemTypes.None
}
}
And then you will be able to use it like this:
xml.ToEnum();
Create an extension for XmlElement that is a wrapper around Enum.Parse:
static TEnum ParseEnum <TEnum>(this XmlElement element) where TEnum : struct, Enum
{
return Enum.Parse<TEnum>(element.Value);
}
Then use like:
ItemType = xml.Element("ItemType")?.ParseEnum<ProjectTreeItemTypes>() ?? ProjectTreeItemTypes.None;
Or you could make the extension responsible for returning the default:
static TEnum TryParseEnum <TEnum>(this XmlElement element, TEnum defaultValue) where TEnum : struct, Enum
{
if (Enum.TryParse<TEnum>(element.Value, out var val))
{
return val;
}
return defaultValue;
}
Usage:
ItemType = xml.Element("ItemType").TryParseEnum(ProjectTreeItemTypes.None);
Basically I want the following generic function:
public string StringOrNull<T> (T value)
{
if (value != null)
{
return value.ToString();
}
return null;
}
I know I could use a constraint such as where T: class, but T can be a primitive type, Nullable<>, or a class. Is there a generic way to do this?
Edit
Turns out I jumped the gun. This actually works just fine as this sample shows:
class Program
{
static void Main(string[] args)
{
int i = 7;
Nullable<int> n_i = 7;
Nullable<int> n_i_asNull = null;
String foo = "foo";
String bar = null;
Console.WriteLine(StringOrNull(i));
Console.WriteLine(StringOrNull(n_i));
Console.WriteLine(StringOrNull(n_i_asNull));
Console.WriteLine(StringOrNull(foo));
Console.WriteLine(StringOrNull(bar));
}
static private string StringOrNull<T>(T value)
{
if (value != null)
{
return value.ToString();
}
return null;
}
}
default Keyword in Generic Code
In generic classes and methods, one issue that arises is how to assign a default value to a parameterized type T when you do not know the following in advance:
Whether T will be a reference type or a value type.
If T is a value type, whether it will be a numeric value or a struct.
Here's a fun one:
public static class ExtensionFunctions{
public static string ToStringOrNull( this object target ) {
return target != null ? target.ToString() : null;
}
}
The cool part? This will work:
( (string) null ).ToStringOrNull();
So will this:
5.ToStringOrNull();
Extension functions are pretty awesome... they even work on null objects!
If you pass a primitive type, it will automatically be boxed, so you don't need to worry about the null comparison. Since boxing occurs automatically, you can even explicitly compare an int to null without an error, but the result will always be false (and you'll probably get a compiler warning telling you so).
You can use default keyword to return the default of T:
public string StringOrNull<T> (T value)
{
.....
return default(T).ToString();
}
Why generic?
public string StringOrNull (object value)
{
if (value != null){
return value.ToString();
}
return null;
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Type result with Ternary operator in C#
I ran into this scenario, and there doesn't seem to be a natural way to return a nullable int. The code below gives compilation error because the ternary operator doesn't like null.
public int? userId
{
get
{
int rv;
return int.TryParse(userIdString, out rv) ? rv : null;
}
}
So you (or just me) really have to go all the way and spell it all out:
public int? userId
{
get
{
int id;
if(int.TryParse(userIdString, out id)){
return id;
}
return null;
}
}
EDIT: Is there a more natural way of instantiating a nullable, to make the ternary operator work?
public int? userId
{
get
{
int rv;
return int.TryParse(userIdString, out rv) ? (int?)rv : null;
}
}
public int? userId
{
get
{
int rv;
return int.TryParse(userIdString, out rv) ? (int?)rv : null;
}
}
EDIT: I hadn't read the question carefully enough; the problem isn't that the conditional operator doesn't like nulls - it's that it needs to know what the overall type of the expression should be... and that type has to be the type of either the left-hand side, or the right-hand side. null itself is a type-less expression which can be converted to many types; int is a perfectly valid type, but it's one of the types which null can't be converted to. You can either make the right-hand side explicitly of type int? and get the implicit conversion of int to int? from the left-hand side, or you can perform a cast on the left-hand side, and get the implicit conversion of null to int?.
My answer is like James's, but casting the null instead:
public int? userId
{
get
{
int rv;
return int.TryParse(userIdString, out rv) ? rv : (int?) null;
}
}
This is to emphasize that it's not a null reference; it's a null value of type int?. At that point, the conversion of the int rv is obvious.
There are two other alternatives along the same lines to consider though:
return int.TryParse(userIdString, out rv) ? rv : new int?();
return int.TryParse(userIdString, out rv) ? rv : default(int?);
Personally I think the "casted null" is the nicest form, but you can make up your own mind.
Another alternative would be to have a generic static method:
public static class Null
{
public static T? For<T>() where T : struct
{
return default(T?);
}
}
and write:
return int.TryParse(userIdString, out rv) ? rv : Null.For<int>();
I don't think I really like that, but I offer it for your inspection :)
You're returning a (non-nullable) int or null in the same expression. You'll need to explicitly return a int? in your ternary expression for that to work.
Is it possible to overload the null-coalescing operator for a class in C#?
Say for example I want to return a default value if an instance is null and return the instance if it's not. The code would look like something like this:
return instance ?? new MyClass("Default");
But what if I would like to use the null-coalescing operator to also check if the MyClass.MyValue is set?
Good question! It's not listed one way or another in the list of overloadable and non-overloadable operators and nothing's mentioned on the operator's page.
So I tried the following:
public class TestClass
{
public static TestClass operator ??(TestClass test1, TestClass test2)
{
return test1;
}
}
and I get the error "Overloadable binary operator expected". So I'd say the answer is, as of .NET 3.5, a no.
According to the ECMA-334 standard, it is not possible to overload the ?? operator.
Similarly, you cannot overload the following operators:
=
&&
||
?:
?.
checked
unchecked
new
typeof
as
is
Simple answer: No
C# design principles do not allow operator overloading that change semantics of the language. Therefore complex operators such as compound assignment, ternary operator and ... can not be overloaded.
This is rumored to be part of the next version of C#. From http://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated
7. Monadic null checking
Removes the need to check for nulls before accessing properties or methods. Known as the Safe Navigation Operator in Groovy).
Before
if (points != null) {
var next = points.FirstOrDefault();
if (next != null && next.X != null) return next.X;
}
return -1;
After
var bestValue = points?.FirstOrDefault()?.X ?? -1;
I was trying to accomplish this with a struct I wrote that was very similar Nullable<T>. With Nullable<T> you can do something like
Nullable<Guid> id1 = null;
Guid id2 = id1 ?? Guid.NewGuid();
It has no problem implicitly converting id1 from Nullable<Guid> to a Guid despite the fact that Nullable<T> only defines an explicit conversion to type T. Doing the same thing with my own type, it gives an error
Operator '??' cannot be applied to operands of type 'MyType' and
'Guid'
So I think there's some magic built into the compiler to make a special exception for Nullable<T>. So as an alternative...
tl;dr
We can't override the ?? operator, but if you want the coalesce operator to evaluate an underlying value rather than the class (or struct in my case) itself, you could just use a method resulting in very few extra keystrokes required. With my case above it looks something like this:
public struct MyType<T>
{
private bool _hasValue;
internal T _value;
public MyType(T value)
{
this._value = value;
this._hasValue = true;
}
public T Or(T altValue)
{
if (this._hasValue)
return this._value;
else
return altValue;
}
}
Usage:
MyType<Guid> id1 = null;
Guid id2 = id1.Or(Guid.Empty);
This works well since it's a struct and id1 itself can't actually be null. For a class, an extension method could handle if the instance is null as long as the value you're trying to check is exposed:
public class MyClass
{
public MyClass(string myValue)
{
MyValue = myValue;
}
public string MyValue { get; set; }
}
public static class MyClassExtensions
{
public static string Or(this MyClass myClass, string altVal)
{
if (myClass != null && myClass.MyValue != null)
return myClass.MyValue;
else
return altVal;
}
}
Usage:
MyClass mc1 = new MyClass(null);
string requiredVal = mc1.Or("default"); //Instead of mc1 ?? "default";
If anyone is here looking for a solution, the closest example would be to do this
return instance.MyValue != null ? instance : new MyClass("Default");