I understand the ?? operator in C#, it looks useful in some cases, it returns the first operand that is not null, or the default value for the type with value types and null with reference types.
With ?? you can replace
int? x = null;
int y = x != null ? x : -1;
With
int? x = null;
int y = x ?? -1;
What I seem to need more often is something like the opposite of it.
An operator which returns null if the first operand is null, or the value of the second operand if the first is not null.
I'd like something to replace
Customer customer = null;
string custname = customer != null ? customer.Name : null;
With
Customer customer = null;
string custname = customer ~? customer.Name;
Wouldn't something like that be a good idea?
-
-
eddwo wrote:
string custname = customer ~? customer.Name;
Wouldn't something like that be a good idea?
No. Having an opposite infers there are two values possible: current and the opposite. This can be represented by a bool. Which has two values true and false. Which implements the not operator. (if it is true return false and vice versa)
Another approach, I would recommend making an interface and implementing it if the need is pervausive.
public interface IInversable<T>
{
public T Opposite();
} -
I would introduce the a new variant of . operator that works with null references. Something like .? ex: name = Customer.?Name, or
adrees = Customer.?Adress.?City.?Name
The .? operator should return left side type default value when used on a null object.
But in any case the only possible value this might add is a little sugar on the sintax expecially where there are lot's of null tests (wich happens to be the case many times when working with object hierachies and there is lot's of drilling operations done on the hierarchy). -
I had exactly the same idea some time ago.
I choosed ?. over .? cos that way it plays better with other constucts like... :
- Indexers: dic?[2]
- Functions: person?.SayHelo()
- Delegates: myDelegate?()
It also has de behavior of 'do nothing' (and returning null if is a function, so is sort circuit like &&).
My post is in the Linq forum:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2038330&SiteID=1
Come on, let's make the idea move and Anders to work a bit more.
Olmo. -
I am not sure the concern deserves its own operator. I think functions as showed would provide clear code. Charecter soups is hard to follow.
-
For me
string bossName=null;
if(Departament!=null)
{
Person boss = Departamente.Boss;
if( boss != null)
bossName = boss.Name;
}
is harder to read than
string bossName = Departament?.Boss?.Name
But also, the second one is an expression, so is possible to be written in a query! while the other one is not. -
olmobrutall wrote:For me
string bossName=null;
if(Departament!=null)
{
Person boss = Departamente.Boss;
if( boss != null)
bossName = boss.Name;
}
is harder to read than
string bossName = Departament?.Boss?.Name
But also, the second one is an expression, so is possible to be written in a query! while the other one is not.
string.IsNullOrEmpty(Department.Boss.Name) ? "": Department.Boss.Name;
Or you could coalesce at the database level if you store is SQL Server.
http://www.brettb.com/SQL_Help_Coalesce_Statement.asp
Linq offer similair functionality: FirstOrDefault Operator or you could also use the string.IsNullOrEmpty in the WHERE clause.
Hope this helps.
-
string.IsNullOrEmpty(Department.Boss.Name) ? "": Department.Boss.Name;
That won't work the way you think it will.
It would throw an exception if the department did not have a boss, since it must evaluate the whole expression before passing it as a parameter. -
eddwo wrote:
string.IsNullOrEmpty(Department.Boss.Name) ? "": Department.Boss.Name;
That won't work the way you think it will.
It would throw an exception if the department did not have a boss, since it must evaluate the whole expression before passing it as a parameter.
You should always test an object for instantiation before you use it. Writing a generic 'IsNull()' function is pretty easy. -
odujosh wrote:

eddwo wrote:
string.IsNullOrEmpty(Department.Boss.Name) ? "": Department.Boss.Name;
That won't work the way you think it will.
It would throw an exception if the department did not have a boss, since it must evaluate the whole expression before passing it as a parameter.
You should always test an object for instantiation before you use it. Writing a generic 'IsNull()' function is pretty easy.
What's the benefit of:
IsNull(foo.Bar) instead of foo.Bar != null? -
string bossName=null;
if(!Departament.IsNull())
{
Person boss = Departamente.Boss;
if(!boss.IsNull())
bossName = boss.Name;
}
Something like this?
Could work as an extension method, but anyway is not very handy, isn't it?
In my post I have an implementation that uses TryXXX extension methods over any type. But because of the limitations of overloading with generic constraints, the name becomes are a bit ugly. (you can“t call all of the methods just 'Try')
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2033762&SiteID=1 -
Yes. Is ugly and a simple:
if (Department != null)
is easier to read... at least for me.
Especially with
if (!Department.IsNull())
you have to look at two different positions to understand what you do here. First at the method name and then at the not operator in front of Department. -
olmobrutall wrote:string bossName=null;
if(!Departament.IsNull())
{
Person boss = Departamente.Boss;
if(!boss.IsNull())
bossName = boss.Name;
}
That wouldn't work either would it?
If "Department" was in fact null, it wouldn't be there to have the "IsNull()" method called on it.
I'm not entirely sure how it works with extension methods, but it seems pretty wierd either way. -
eddwo wrote:

olmobrutall wrote:
string bossName=null;
if(!Departament.IsNull())
{
Person boss = Departamente.Boss;
if(!boss.IsNull())
bossName = boss.Name;
}
That wouldn't work either would it?
If "Department" was in fact null, it wouldn't be there to have the "IsNull()" method called on it.
I'm not entirely sure how it works with extension methods, but it seems pretty wierd either way.
If Department is the class name and department is a Department object:
Department department = new Department()
then you could use a static
Department.IsNull(department);
static bool Department.IsNull(Department d){
return d == null;
}
but I agree it's dumb and ugly.
-
Works on extension methods because the first argument (marked in C# with the this keyword) can be null. This this keyword is just there to have you not to set the ExtensionMethodAttribute set on the method. The extension method would look like this:eddwo wrote:That wouldn't work either would it?
If "Department" was in fact null, it wouldn't be there to have the "IsNull()" method called on it.
I'm not entirely sure how it works with extension methods, but it seems pretty wierd either way.
public static class ObjectExtension
{
public static bool IsNull(this object value)
{
return value == null;
}
}
Yeah and it is ugly
-
littleguru wrote:
public static class ObjectExtension
{
public static bool IsNull(this object value)
{
return value == null;
}
}
So with C# 3 you could have something like
public static class ObjectExtension
{
public static R NNV(this object value,Func<T,R> prop)
{
return value != default(T) ? prop(value) : default(R);
}
}
and then have an expression like
Person person = null;
string bossname = person.NNV(p => p.Department).NNV(d => d.Boss).NNV(b => b.Name);
Where NNV stands for "NonNullValue"
(No I don't know my lambda expression syntax very well, and I haven't tested it either)
-
Would look something like this:
public static class ObjectExtension
{
public static TResult IsNull<T, TResult>(this object value, Func<T, TResult> func)
{
return value == null ? default(TResult) : func((T)value);
}
}
and is a pain to be used:
Bar f1 = f.IsNull<Foo, Bar>(x => x.Bar).IsNull<Bar, Foo>(y => y.Foo).IsNull<Foo, Bar>(z => z.Bar); -
I see. I was assuming it could infer the types of the generic NNV method from the types of the lambda expression, but in actual fact it would have to infer the types of the lambda expression from the specified generic method type parameters.
Yes that does make it much too long winded to drill down much more than one level in an object graph.
(Still I'm quite pleased I got it fairly close :0) )
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.