What to name a variant of a Get() method? - c#

I am developing an API for a repository-like abstraction. I have two methods:
// Throws an exception if object cannot be found
MyObj Get(MyIdType id);
// Returns false if object cannot be found; no exception
bool TryGet(out MyObj obj);
There is a requirement for a third variant: one that returns null if object cannot be found, and does not throw an exception.
// Returns null if object cannot be found; no exception
MyObj ?????(MyIdType id);
I'm stuck as on what to name it. GetOrDefault has been ruled out as confusing. GetIfNotNull has been suggested, but also seems unclear. GetOrNull is the most promising so far.
Does anyone have any other suggestions, or know of any public APIs whose conventions I can follow?

I would opt to not have a Get method that behaves differently in two situations. Why not have the Get return null for all cases. Why throw an exception at all?
I would opt to leave it up to user code to throw an exception if a null value is returned, if required.
See this question for further guidance related to when to throw exceptions.

I'd go with GetOrDefault (as you suggested yourself) based on the LINQ extension method FirstOrDefault.
Maybe GetValue and GetValueOrDefault would sound better though.

How about: GetOrDefault
The ...OrDefault is fairly standard in LINQ.

You could try GetObjectOrReturnDefaultValue or, since you know it's a reference type GetObjectOrReturnNull. It's long and ugly, but it's not ambiguous.

I'd keep only bool TryGetXXXXX(out T value) variant on your interface and provide the rest as extension methods to it. It makes your interface itself very compact, but at the same time as useful as client wants.

In my opinion, you should stick with:
MyObj Get(MyIdType id);
Instead of throwing an exception here, simply return null. If there is a definite requirement to throw an exception or optionally, null, I would try:
MyObj Get (MyIdType id, bool ReturnDefault = false) // if .net 4
I don't particularly like this option - but sometimes requirements will override what we think feels right or natural.

Related

When Implementing IEqualityComparer Should GetHashCode check for null?

When implementing IEqualityComparer<Product> (Product is a class), ReSharper complains that the null check below is always false:
public int GetHashCode(Product product)
{
// Check whether the object is null.
if (Object.ReferenceEquals(product, null))
return 0;
// ... other stuff ...
}
(Code example from MSDN VS.9 documentation of Enumerable.Except)
ReSharper may be wrong, but when searching for an answer, I came across the official documentation for IEqualityComparer<T> which has an example where null is not checked for:
public int GetHashCode(Box bx)
{
int hCode = bx.Height ^ bx.Length ^ bx.Width;
return hCode.GetHashCode();
}
Additionally, the documentation for GetHashCode() states that ArgumentNullException will be thrown when "The type of obj is a reference type and obj is null."
So, when implementing IEqualityComparer should GetHashCode check for null, and if so, what should it do with null (throw an exception or return a value)?
I'm interested most in .NET framework official documentation that specifies one way or another if null should be checked.
ReSharper is wrong.
Obviously code you write can call that particular GetHashCode method and pass in a null value. All known methods might ensure this will never happen, but obviously ReSharper can only take existing code (patterns) into account.
So in this case, check for null and do the "right thing".
Corollary: If the method in question was private, then ReSharper might analyze (though I'm not sure it does) the public code and verify that there is indeed no way that this particular private method will be called with a null reference, but since it is a public method, and one available through an interface, then
ReSharper is wrong.
The documentation says that null values should never be hashable, and that attempting to do so should always result in an exception.
Of course, you're free to do whatever you want. If you want to create a hash based structure for which null keys are valid, you're free to do so, in this case you should simply ignore this warning.
ReSharper has some special case code here. It will not warn about the ReferenceEquals in this:
if (ReferenceEquals(obj, null)) { throw new ArgumentNullException("obj"); }
It will warn about the ReferenceEquals in this:
if (ReferenceEquals(obj, null)) { return 0; }
Throwing an ArgumentNullException exception is consistent with the contract specified in IEqualityComparer(Of T).GetHashCode
If you go to the definition of IEqualityComparer (F12) you'll also find further documentation:
// Exceptions:
// System.ArgumentNullException:
// The type of obj is a reference type and obj is null.
int GetHashCode(T obj);
So ReSharper is right that there is something wrong, but the error displayed doesn't match the change you should make to the code.
There is some nuance to this question.
The docs state that IEqualityComparer<T>.GetHashCode(T) throws on null input; however EqualityComparer<>.Default - which is almost certainly by far the most used implementation - does not throw.
Clearly, an implementation does not need to throw on null it merely has the option too.
However, I'd argue that no implementation should ever throw on null here, it's just confusing, and a possible source of bugs. Exceptions are a pain in any case, being a non-local control flow mechanism, and that alone argues for using them when necessary only (i.e.: not here). But additionally, for IEqualityComparer specifically, the docs state that whenever Equals(x, y) then GetHashCode(x) should equal GetHashCode(y) - and Equals does allow nulls, and is not documented as throwing any exceptions.
The invariant that equality implies hashcode equality makes implementing things relying on those hashcodes much simpler. Having a gotcha with the null value is a design cost you should avoid paying without need. And here there is no need, ever.
In short:
do not throw from GetHashCode, even though it is allowed
and do check for nulls; Resharper's warning is incorrect.
Doing this results in simpler code with fewer gotchas, and it follows the behavior of EqualityComparer<>.Default which is the most common implementation used.

Is there a way to mark a method as ensuring that T is not null?

For example, if I have a method defined as...
T Create()
{
T t = Factory.Create<T>();
// ...
Assert.IsNotNull(t, "Some message.");
// -or-
if (t == null) throw new Exception("...");
// -or- anything that verifies that it is not null
}
...and I am calling that method from somewhere else...
void SomewhereElse()
{
T t = Create();
// >><<
}
...at >><<, I know (meaning me, the person who wrote this) that t is guaranteed to not be null. Is there a way (an attribute, perhaps, that I have not found) to mark a method as ensuring that a reference type that it returns or otherwise passes out (perhaps an out parameter) is guaranteed by internal logic to not be null?
I have to sheepishly admit that ReSharper is mostly why I care as it highlights anything it thinks could cause either InvalidOperationException or NullReferenceException. I figure either it's reading something that I can mark on my methods or it just knows that Assert.IsNotNull, simple boolean checks or a few other things will remove the chance of something being null and that it can remove the highlight.
Any thoughts? Am I just falling victim to oh-my-god-resharper-highlights-it-I-have-to-fix-it disease?
If ReSharper is why you care then you can mark the Factory.Create<T>() method with their [NotNull] attribute described in their web help
Not sure how R# handles this, but the Contract.Assert method may be what you're looking for
You could put a constraint on T to only allow struct.
You could use a language extension that allows you to make stronger definitions of pre/post conditions for your function (contract based programming), like SpecSharp, or Code Contracts. Code Contracts seems to leverage built-in systems from C# 4.0. I have no experience with either - only heard of them.
Could you cast T to an object then check if its null?
var o = (object)Factory.Create<T>();
if(o == null) throw new Exception();

Why ever cast reference types when you can use "as"? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Casting: (NewType) vs. Object as NewType
In C#, why ever cast reference types when you can use "as"?
Casting can generate exceptions whereas "as" will evaulate to null if the casting fails.
Wouldn't "as" be easier to use with reference types in all cases?
eg:
MyObject as DataGridView
rather than,
(DataGridView)MyObject
Consider the following alternatives:
Foo(someObj as SomeClass);
and:
Foo((SomeClass)someObj);
Due to someObj being of the wrong type, the first version passes null to Foo. Some time later, this results in a NullReferenceException being thrown. How much later? Depends on what Foo does. It might store the null in a field, and then minutes later it's accessed by some code that expects it to be non-null.
But with the second version, you find the problem immediately.
Why make it harder to fix bugs?
Update
The OP asked in a comment: isn't is easier to use as and then check for null in an if statement?
If the null is unexpected and is evidence of a bug in the caller, you could say:
SomeClass c = someObj as SomeClass;
if (c == null)
{
// hmm...
}
What do you do in that if-block? There are two general solutions. One is to throw an exception, so it is the caller's responsibility to deal with their mistake. In which case it is definitely simpler to write:
SomeClass c = (SomeClass)someObj;
It simply saves you writing the if/throw logic by hand.
There is another alternative though. If you have a "stock" implementation of SomeClass that you are happy to use where nothing better is available (maybe it has methods that do nothing, or return "empty" values, etc.) then you could do this:
SomeClass c = (someObj as SomeClass) ?? _stockImpl;
This will ensure that c is never null. But is that really better? What if the caller has a bug; don't you want to help find bugs? By swapping in a default object, you disguise the bug. That sounds like an attractive idea until you waste a week of your life trying to track down a bug.
(In a way this mimics the behaviour of Objective-C, in which any attempt to use a null reference will never throw; it just silently does nothing.)
operator 'as' work with reference types only.
Sometimes, you want the exception to be thrown. Sometimes, you want to try to convert and nulls are OK. As already stated, as will not work with value types.
One definite reason is that the object is, or could be (when writing a generic method, you may not know at coding-time) being cast to a value type, in which case as isn't allowed.
One more dubious reason is that you already know that the object is of the type in question. Just how dubious depends on how you already know that. In the following case:
if(obj is MyType)
DoMyTypeStuff((MyType)obj);
else
DoMoreGeneralStuff(obj);
It's hard to justify using as here, as the only thing it really does is add a redundant check (maybe it'll be optimised away, maybe it won't). At the other extreme, if you are half-way to a trance state with the amount of information you've got in you're brain's paged-in memory and on the basis of that you are pretty sure that the object must be of the type in question, maybe it's better to add in the check.
Another good reason is that the difference between being of the wrong type and being null gets hidden by as. If it's reasonable to be passing in a string to a given method, including a null string, but it's not reasonable to pass in an int, then val as string has just made the incorrect usage look like a completely different correct usage, and you've just made the bug harder to find and potentially more damaging.
Finally, maybe if you don't know the type of the object, the calling code should. If the calling code has called yours incorrectly, they should receive an exception. To either allow the InvalidCastException to pass back, or to catch it and throw an InvalidArgument exception or similar is a reasonable and clear means of doing so.
If, when you write the code to make the cast, you are sure that the cast should work, you should use (DataGridView)MyObject. This way, if the cast fails in the future, your assumption about the type of MyObject will cause an invalid cast exception at the point where you make the cast, instead of a null reference exception at some point later.
If you do want to handle the case where MyObject is not a DataGridView, then use as, and presumably check for it being null before doing anything with it.
tl;dr If your code assumes something, and that assumption is wrong at run-time, the code should throw an exception.
From MSDN (as (C# reference)):
the as operator only performs reference conversions and boxing conversions. The as operator cannot perform other conversions, such as user-defined conversions, which should instead be performed using cast expressions.
Taking into consideration all of the comments, we came across this just the other day and wondered why you would do a direct cast over using the keyword as. What if you want the cast to fail? This is sometimes the desirable effect you want from a cast if you're casting from a null object. You then push the exception up the call stack.
So, if you want something to fail, use a direct cast, if you're okay with it not failing, use the as keyword.
As is faster and doesn't throw exceptions. Therefore it is generally preferred. Reasons to use casts include:
Using as, you can only assign types that are lower in the inheritance tree to ones that are higher. For example:
object o = "abc" as object;
DataGridView d = "abc" as DataGridView // doesn't do anything
DataGridView could create a custom cast that does allow this. Casts are defined on the target type and therefore allow everything, as long as it's defined.
Another problem with as is that it doesn't always work. Consider this method:
IEnumerable<T> GetList<T>(T item)
{
(from ... select) as IEnumerable<T>
}
This code fails because T could also be a Value Type. You can't use as on those because they can never be null. This means you'll have to put a constraint on T, while it is actually unnecesary. If you don't know whether you're going to have a reference type or not, you can never use as.
Of course, you should always check for null when you use the as keyword. Don't assume no exceptions will be thrown just becase the keyword doesn't throw any. Don't put a Try {} Catch(NullReferenceException){} around it, that't unneccesary and bloat. Just assign the value to a variable and check for null before you use it. Never use it inline in a method call.

Is there a reason to do a type comparison this way?

I'm used to seeing old code like
if (true)
{
...
}
where it's intuitively clear that someone was being either lazy or overly cautious when making a change. I ran across this snippet today, and I'm curious whether there's a functional difference between doing type comparison this way:
private static bool logField(Type t, string fieldname)
{
if (t.ToString() == typeof (Property).ToString())
{
...
}
return true;
}
and doing it this way:
private static bool logField(Type t, string fieldname)
{
if (t == typeof (Property))
{
...
}
return true;
}
I'd say that's generally laziness - but it may not be. For example, you could have two Property types, in the same effective file, but different copies. If typeof(Property) loads it from one file but t is loaded from a different one, your replacement would say they were different but the original code would compare say they were the same.
It's definitely an edge case, and one that you normally want to avoid in the first place... but it's just possible.
I can't think of any good reasons.
In fact, the former will throw if t is null.
The first one compares references of Strings, while the second one actually checks to see if t is of the Property type.
The first one will always be "correct" because the two strings refer to the same object, but the second one is the correct way to check if t is of the Property type.
An equivalent and more readable way to do a type check is
if (t is Property)
No, getting the type object of 2 instances of the same type will always return a reference to the same type object in memory. This means that performing a reference equality check (==) is sufficient.
Essentially, calling:
if (t.ToString() == typeof (Property).ToString())
will call ToString() twice on the same object, where t is the 'Property' type.
I'd say that the first approach was probably done by someone unfamiliar with C#, not necessary being lazy. The string comparison will work for a majority of the time, except:
If t is null it would throw a null reference exception.
It doesn't take namespaces into consideration.
I would recommend the second case, unless you fall into needing the #2 edge case.

C#: Should I bother checking for null in this situation?

Lets say I have this extention method:
public static bool HasFive<T>(this IEnumerable<T> subjects)
{
if(subjects == null)
throw new ArgumentNullException("subjects");
return subjects.Count() == 5;
}
Do you think this null check and exception throwing is really necessary? I mean, when I use the Count method, an ArgumentNullException will be thrown anyways, right?
I can maybe think of one reason why I should, but would just like to hear others view on this. And yes, my reason for asking is partly laziness (want to write as little as possible), but also because I kind of think a bunch of null checking and exception throwing kind of clutters up the methods which often end up being twice as long as they really needed to be. Someone should know better than to send null into a method :p
Anyways, what do you guys think?
Note: Count() is an extension method and will throw an ArgumentNullException, not a NullReferenceException. See Enumerable.Count<TSource> Method (IEnumerable<TSource>). Try it yourself if you don't believe me =)
Note2: After the answers given here I have been persuaded to start checking more for null values. I am still lazy though, so I have started to use the Enforce class in Lokad Shared Libraries. Can recommend taking a look at it. Instead of my example I can do this instead:
public static bool HasFive<T>(this IEnumerable<T> subjects)
{
Enforce.Argument(() => subjects);
return subjects.Count() == 5;
}
Yes, it will throw an ArgumentNullException. I can think of two reasons for putting the extra checking in:
If you later go back and change the method to do something before calling subjects.Count() and forget to put the check in at that point, you could end up with a side effect before the exception is thrown, which isn't nice.
Currently, the stack trace will show subjects.Count() at the top, and probably with a message with the source parameter name. This could be confusing to the caller of HasFive who can see a subjects parameter name.
EDIT: Just to save me having to write it yet again elsewhere:
The call to subjects.Count() will throw an ArgumentNullException, not a NullReferenceException. Count() is another extension method here, and assuming the implementation in System.Linq.Enumerable is being used, that's documented (correctly) to throw an ArgumentNullException. Try it if you don't believe me.
EDIT: Making this easier...
If you do a lot of checks like this you may want to make it simpler to do so. I like the following extension method:
internal static void ThrowIfNull<T>(this T argument, string name)
where T : class
{
if (argument == null)
{
throw new ArgumentNullException(name);
}
}
The example method in the question can then become:
public static bool HasFive<T>(this IEnumerable<T> subjects)
{
subjects.ThrowIfNull("subjects");
return subjects.Count() == 5;
}
Another alternative would be to write a version which checked the value and returned it like this:
internal static T NullGuard<T>(this T argument, string name)
where T : class
{
if (argument == null)
{
throw new ArgumentNullException(name);
}
return argument;
}
You can then call it fluently:
public static bool HasFive<T>(this IEnumerable<T> subjects)
{
return subjects.NullGuard("subjects").Count() == 5;
}
This is also helpful for copying parameters in constructors etc:
public Person(string name, int age)
{
this.name = name.NullGuard("name");
this.age = age;
}
(You might want an overload without the argument name for places where it's not important.)
I think #Jon Skeet is absolutely spot on, however I'd like to add the following thoughts:-
Providing a meaningful error message is useful for debugging, logging and exception reporting. An exception thrown by the BCL is less likely to describe the specific circumstances of the exception WRT your codebase. Perhaps this is less of an issue with null checks which (most of the time) necessarily can't give you much domain-specific information - 'I was passed a null unexpectedly, no idea why' is pretty much the best you can do most of the time, however sometimes you can provide more information and obviously this is more likely to be relevant when dealing with other exception types.
The null check clearly demonstrates to other developers and you, a form of documentation, if/when you come back to the code a year later, that it's possible someone might pass a null, and it would be problematic if they did so.
Expanding on Jon's excellent point - you might do something before the null gets picked up - I think it is vitally important to engage in defensive programming. Checking for an exception before running other code is a form of defensive programming as you are taking into account things might not work the way you expected (or changes might be made in the future that you didn't expect) and ensuring that no matter what happens (assuming your null check isn't removed) such problems cannot arise.
It's a form of runtime assert that your parameter is not null. You can proceed on the assumption that it isn't.
The above assumption can result in slimmer code, you write the rest of your code knowing the parameter is not null, cutting down on extraneous subsequent null checks.
In my opinion you should check for the null value. Two things that comes to mind.
It makes explicit the possible errors that can happen during runtime.
It also gives you a chance to throw a better exception instead of a generic ArgumentNullException. Thus, making the reason for the exception more explicit.
The exception that you will get thrown will be an Object reference not set to an instance of an object.
Not the most useful of exceptions when tracking down the problem.
The way you have it there will give you much more useful information by specifically stating that it's your subjects reference that is null.
I think it is a good practice to do precondition checks at the top of the function. Maybe it's just my code that is full of bugs, but this practice catched a lot of errors for me.
Also, it's much easier to figure out the source of the problem if you got an ArgumentNullException with the name of the parameter, thrown from the most relevant stack frame. Also, the code in the body of your function can change over time so I wouldn't depend on it catching precondition problems in the future.
It always depends on the context (in my opinion).
For instance, when writing a library (for others to use), it certainly makes sense to fully check each and every parameter and throw the appropriate exceptions.
When writing methods that are used inside a project, I usually skip those checks, attempting to reduce the size of the codebase. But even in this case, there might be a level (between application layers) where you still place such checks. It depends on the context, on the size of the project, on the size of the team working on it...
It certainly doesn't make sense doing it for small projects built by one person :)
It depends on the concrete method. In this case - I think, the exception is not necesary and the better usage will be, if teh extension method can deal with null.
public static bool HasFive<T>(this IEnumerable<T> subjects) {
if ( object.ReferenceEquals( subjects, null ) ) { return false; }
return subjects.Count() == 5;
}
If you call "items.HasFive()" and the "items" is null, then is true that items has not five items.
But if you have extension method:
public static T GetFift<T>(this IEnumerable<T> subjects) {
...
}
The exception for "subjects == null" should be called, because there is no valid way, how to deal with it.
If you look at the source to the Enumerable class (System.Core.dll) where a lot of the default extension methods are defined for IEnumerables classes, you can see that they all check for null references with arguments.
public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
return SkipIterator<TSource>(source, count);
}
It's a bit of an obvious point, but I tend to follow what I find in the base framework library source as you know that is more than likely to be best practices.
Yes, for two reasons:
Firstly, the other extension methods on IEnumerable do and consumers of your code can expect yours to do so as well, but secondly and more importantly, if you have a long chain of operators in your query then knowing which one threw the exception is useful information.
In my opinion one should check for known conditions that will raise errors later on (at least for public methods). That way it's easier to detect the root of the problem.
I would raise a more informational exception like:
if (subjects == null)
{
throw new ArgumentNullException("subjects ", "subjects is null.");
}

Categories

Resources