How to prevent static method from creating a null object - c#

I have a static method that I call that checks if an object should be added and if calls the constructor if it should add it. Then if not it should really do nothing. I thought returning null would achieve this but it is creating an object with none of the properties being populated. This is then causing a runtime eror later.
This is my code:
public static WorkSheets AddSheet(string dataPath, string exportFile, string finalFile, string tabName)
{
if (File.Exists(dataPath + exportFile))
{
if (!tabName.Contains("Forecast") & !tabName.Contains("Sales"))
if (Functions.FileIsGood(dataPath + exportFile)) File.Copy(dataPath + exportFile, dataPath + finalFile, true);
return new WorkSheets(dataPath, exportFile, finalFile, tabName);
}
return null;
}
and my constructor:
public WorkSheets(string dataPath, string exportFile, string finalFile, string tabName)
{
this.ExportFile = dataPath + exportFile;
this.Path = dataPath + finalFile;
this.TabName = tabName;
this.DateError = !Functions.IsTodaysDate(ExportFile);
this.WorksheetDate = File.GetLastWriteTime(ExportFile);
this.SizeError = !Functions.IsCorrectSize(ExportFile);
this.WorksheetSize = new FileInfo(ExportFile).Length;
}
Then I call the method like this:
worksheets.Add(WorkSheets.AddSheet(CurrentWorkbook.DataPath, Constants.PipeExport, Constants.PipeFinalFile, "Pipe"));
The issue I am having is with the return null; what can I do so it doesn't add the null object.

You just need to get the return value from AddSheet in a temporary variable and check if it is null.
If it is null just don't add it to your list of worksheets
WorkSheets sheet = WorkSheets.AddSheet(CurrentWorkbook.DataPath,
Constants.PipeExport,
Constants.PipeFinalFile,
"Pipe"));
if(sheet != null)
worksheets.Add(sheet);
If you prefer to avoid repeating this check every time you add an element to the list then you can create a new class derived from List<T> and write your own Add method that performs the check for null and add to the underlying base class if the element to add is not null.
public class ListWorkSheets : List<WorkSheets>
{
public new void Add(WorkSheets source)
{
if(source != null)
base.Add(source);
}
}
Now you can declare
ListWorkSheets worksheets = new ListWorkSheets();
and use your current syntax without adding a null to your list
worksheets.Add(WorkSheets.AddSheet(CurrentWorkbook.DataPath,
Constants.PipeExport,
Constants.PipeFinalFile,
"Pipe"));

Try some conditional logic before adding the instance to the list.
IE
Worksheet tempWorkSheet = WorkSheets.AddSheet(CurrentWorkbook.DataPath, Constants.PipeExport, Constants.PipeFinalFile, "Pipe");
if (tempWorkSheet != null)
{
worksheets.Add(TempWorkSheet);
}

If your method has a declared return type you have to return that type or null.
You could throw an exception instead.
Or you change the return type to void and declare an out parameter for your result
Alternatively you could save the result of your call that instantiates the object and check for null.
var tmp = WorkSheets.AddSheet(foo);
if(tmp != null) {
worksheets.Add(tmp)
}

I'd recommend one of the following:
What #Steve said: split up your function call and check for null in the return.
Wrap your function call in a try/catch block then have your function return an exception if it can't find the file.
If it's a rare anomaly where a file can't be found then the exception is likely the 'correct' way to go from a methodology standpoint. If it's common for incorrect paths to be attempted, then returning null and having a check like Steve said is probably best. It's more a question of code methodology than technical requirement at that point.

Related

How to pass the name of a class as paramenter to a method and instantiate that class inside the method?

I would like to be able to pass a class name as parameter to a method, and then inside that method create an object of that class with certain parameters.
A concrete (simplified) example:
This is a method to compute an OperationResult
private IOperationResult<Unit> GetFailedOperationResult(IEnumerable<StrictSide> sides, IFailedOperationInfo failedOperationResult)
{
var exception = failedOperationResult.Exception.HasValue() ? failedOperationResult.Exception.Value() : null;
if (exception != null)
{
return new FailedResult<Unit>(
new InvalidBundleErrorKeyResolver(new FailedOperationInfo(new OperationInfo(failedOperationResult.OperationName, sides), exception)));
}
throw new InvalidOperationException("Failed operation result during bundle consistency check does not contain error or exception.");
}
Depending on the operation that we get the error from, we use different ErrorKeyResolvers. I would like to pass these ErrorKeyResolver as a parameter to the method, so that I don't need to make different GetFailedOperationResult methods for each error type.
Inspired by How to use class name as parameter in C#
I tried something like this:
private IOperationResult<Unit> GetFailedOperationResult(IEnumerable<StrictSide> sides,IFailedOperationInfo failedOperationResult, IErrorResourceKeyResolver resourceKeyResolver)
{
var exception = failedOperationResult.Exception.HasValue() ? failedOperationResult.Exception.Value() : null;
if (exception != null)
{
return new FailedResult<Unit>(Activator.CreateInstance(typeof(resourceKeyResolver),new FailedOperationInfo(new OperationInfo(failedOperationResult.OperationName, sides), exception)));
}
throw new InvalidOperationException("Failed operation result during bundle consistency check does not contain error or exception.");
}
But I cannot do typeof(resourceKeyResolver) because I cannot use a variable as a type.
Is there a nice way to do this? Is it even a good thing to do? I also read that dynamics should be avoided so I wonder if saving some code repetition is worth it here.
EDIT: the input parameters should be: private IOperationResult<Unit> GetFailedOperationResult(IEnumerable<StrictSide> sides,IFailedOperationInfo failedOperationResult, string resourceKeyResolver)
And from the class name as string I should be able to find the type.
If you pass the class as interface you can use following code to instantiate resolver
var resolver = Activator.CreateInstance(resourceKeyResolver.GetType(),
new FailedOperationInfo(new OperationInfo(failedOperationResult.OperationName,
sides), exception));
Otherwise, if you use the class name (assembly-qualified-name) you can, for example, convert it to type first and call the above line again
var resolverType = Type.GetType(resourceKeyResolverClassName);
var resolver = Activator.CreateInstance(resolverType ,
new FailedOperationInfo(new OperationInfo(failedOperationResult.OperationName,
sides), exception));
See here for documentation of GetType() method

C# "??" operator - what's wrong?

// EWS Microsoft.Exchange.WebServices.Data.Folder
private Folder _historyFolder;
_historyFolder = GetHistroyFolder(exchangeService) ?? CreateHistortFolder(exchangeService);
public Folder GetHistroyFolder(ExchangeService service)
{
//if found the folder I want - return it , otherwise returns null
}
public Folder CreateHistortFolder(ExchangeService service)
{
var folder = new Folder(service);
folder.DisplayName = _historyFolderName; // "who cares" :)
folder.FolderClass = _historyFolderClass; // "IPF.Note"
folder.Save(WellKnownFolderName.MsgFolderRoot);
return folder;
}
For some reason _historyFolder is always null, although GetHistroyFolder(exchangeService) does return a folder. Why is that?
UPDATE I
I have updated proof for the unbelievers !
If I separate it to 2 lines (without ??) it's OK! but I still wanna understand why the first approach doesn't work...
why down vote? mean ppl..
UPDATE II
Thanks for the all warm people who down vote the question / vote for "close" this thread.
And Thanks for the true warm people who are trying ...
I used the workaround approach, split it to 2 lines
_historyFolder = GetHistroyFolder(exchangeService);
if (_historyFolder == null) _historyFolder = CreateHistortFolder(exchangeService);
you know what funny? Resharper suggests me to return it to how it was before...
Yea , this is a workaround and not real answer for WHY and WTF ... ( .net 4.5 )
UPDATE III
if GetHistroyFolder(..) is return null ( when foreach doesn't find ... ) , CreateHistoryFolder does return Folder object , and _historyFolder is getting the value
Instead of a field why dont you use a property with a backing field. This doesn't exactly solve the problem but at least this makes it easier to debug.
Folder historyFolder
{
get{
if(_historyFolder != null)
return _historyFolder;
_historyFolder = GetHistroyFolder(exchangeService);
if(_historyFolder == null)
_historyFolder = CreateHistortFolder(exchangeService)
if(_historyFolder == null)
throw new NullReferenceException("history folder still null");
return _historyFolder;
}
}
There's no reason for _historyFolder to be NULL, if GetHistroyFolder() is returning an object e.g.
namespace ConsoleApplication1
{
class Program
{
// EWS Microsoft.Exchange.WebServices.Data.Folder
private static object _historyFolder;
static void Main(string[] args)
{
_historyFolder = GetHistroyFolder(null) ?? CreateHistortFolder(null);
Console.WriteLine(_historyFolder == null);
}
public static object GetHistroyFolder(object service)
{
return new object();
//if found the folder I want - return it , otherwise returns null
}
public static object CreateHistortFolder(object service)
{
return null;
}
}
}
I can only imagine that _historyFolder is being set to NULL after GetHistroyFolder() has been called. Your code looks incomplete, are you running in an ASP.NET or something?
EDIT:
In your code, where you call FindFolders(new FolderView()) do this:
FindFolders(new FolderView()).ToList()
Because FindFolders returns an IEnumerable, I think you should call ToList() to ensure that all the folders are returned in one go, not just yielded.
may be "CreateHistoryFolder" return null

Return multiple values from a method

Hi guys i'm having a problem regarding returning multiple values from a method. I'm using 'out' to return other value from a method, here the snippet:
public DataTable ValidateUser(string username, string password, out int result)
{
try
{
//Calls the Data Layer (Base Class)
if (objDL != null)
{
int intRet = 0;
sqlDT = objDL.ValidateUser(username, password, out intRet);
}
}
catch (Exception ex)
{
ErrorHandler.Handle(ex);
OnRaiseErrorOccuredEvent(this, new ErrorEventArgs(ex));
}
return sqlDT;
}
then when i compile having a error like this:
"The out parameter 'return' must be assigned to before control leaves the current method"
Anyone guys can help me solve this.
That means in all possibilities (inside and outside the if, in the catch), your result variable must be assigned.
The best approach would be to give it a default value at the start of the function:
public DataTable ValidateUser(string username, string password, out int result)
{
result = 0;
try
{
//Calls the Data Layer (Base Class)
if (objDL != null)
{
int intRet = 0;
sqlDT = objDL.ValidateUser(username, password, out intRet);
result = intRet;
}
//....
The parameter result of your method is marked as out. Parameters marked with out must be assigned within your method, i.e
result = 5;
This is enforced so callers of your method have the guarantee that the parameter that is passed with out is always set once your method finishes.
You're not setting the result variable in the method.
I'm guessing you want to add an extra line such as
result = intRet;

Is it possible to use 'return' and 'out' the same time?

I have a method GetSelectedServices() which returns Selected Nodes from a Tree List,
Expecting to return with the same method selected nodes and all Nodes i tried to add an out parameter.
But when I call this method i'm supposed to give the out parameter and so the returned list with selectedNodes is masked, and i cannot have it.
My Method
internal List<__ServiceInfo> GetSelectedServices(out List<__ServiceInfo> lstAll)
{
List<__ServiceInfo> lstSelected = new List<__ServiceInfo>();
List<__ServiceInfo> lstA = new List<__ServiceInfo>();
foreach (TreeListNode node in this.tlServices.Nodes)
{
if (node.Checked)
{
var service = this.tlServices.GetDataRecordByNode(node) as __ServiceInfo;
lstA.Add(service);
if (service != null)
{
lstSelected.Add(service);
}
if (node.Nodes.Count > 0)
{
foreach (TreeListNode subNode in node.Nodes)
{
if (subNode.Checked)
{
service = this.tlServices.GetDataRecordByNode(subNode) as __ServiceInfo;
lstA.Add(service);
if (service != null)
{
lstSelected.Add(service);
}
}
}
}
}
}
lstAll = lstA;
return lstSelected;
}
The way I call the method
public bool HasValidModel()
{
List<__ServiceInfo> lstAll = new List<__ServiceInfo>();
//here I get all nodes
var allServices = this.GetAllServices(out lstAll);
List<__ServiceInfo> lstSelected = new List<__ServiceInfo>();
//but how to get the list from ""return lstSelected"";
}
thank you for any suggestions.
You've already got two variables, although you're initializing one of them unnecessarily. Just use:
public bool HasValidModel()
{
List<__ServiceInfo> lstAll;
var selectedServices = this.GetAllServices(out lstAll);
// Now use lstAll and selectedServices
}
Personally I don't really like using out parameters much, and would look for an alternative design if possible, but that's a separate matter. (I'd separate out finding all services from selecting some of them.)
Just use two variables, like this:
List<__ServiceInfo> lst;
List<__ServiceInfo> lstSelected = GetSelectedServices(out lst);
The 'return'ed object is now referenced by lstSelected, while the outed object is referenced by lst.
The way you implemented the return and the out parameter seems to be fine. But the call is wrong. #Ken's answer points in the right direction.
However the logic in the GetSelectedServices method is odd. The only difference between a "selected" service and a "regular" service is that a "regular" service is NULL. Which leads to the result that the allServices list is a collection of NULLs plus the selected services. Which makes no sense in my opinion.

Checking if an object is null in C#

I would like to prevent further processing on an object if it is null.
In the following code I check if the object is null by either:
if (!data.Equals(null))
and
if (data != null)
However, I receive a NullReferenceException at dataList.Add(data). If the object was null, it should never have even entered the if-statement!
Thus, I'm asking if this is proper way of checking if an object is null:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
If this is the proper way of checking if the object is null, what am I doing wrong (how can I prevent further processing on the object to avoid the NullReferenceException)?
It's not data that is null, but dataList.
You need to create one with
public List<Object> dataList = new List<Object>();
Even better: since it's a field, make it private. And if there's nothing preventing you, make it also readonly. Just good practice.
Aside
The correct way to check for nullity is if(data != null). This kind of check is ubiquitous for reference types; even Nullable<T> overrides the equality operator to be a more convenient way of expressing nullable.HasValue when checking for nullity.
If you do if(!data.Equals(null)) then you will get a NullReferenceException if data == null. Which is kind of comical since avoiding this exception was the goal in the first place.
You are also doing this:
catch (Exception e)
{
throw new Exception(e.ToString());
}
This is definitely not good. I can imagine that you put it there just so you can break into the debugger while still inside the method, in which case ignore this paragraph. Otherwise, don't catch exceptions for nothing. And if you do, rethrow them using just throw;.
in C# > 7 use if (obj is null)
For not null use:
   C# 7-8:  if (obj is object)
   C# 9-:    if (obj is not null)
These will ignore any == or != defined by the object (unless of course you want to use them for null checks)
For more, in the C# Language Reference, see is operator.
C# 6 has monadic null checking :)
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;
Your dataList is null as it has not been instantiated, judging by the code you have posted.
Try:
public List<Object> dataList = new List<Object>();
public bool AddData(ref Object data)
bool success = false;
try
{
if (!data.Equals(null)) // I've also used if(data != null) which hasn't worked either
{
dataList.Add(data); //NullReferenceException occurs here
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw;
}
return success;
}
[Edited to reflect hint by #kelton52]
Simplest way is to do object.ReferenceEquals(null, data)
Since (null==data) is NOT guaranteed to work:
class Nully
{
public static bool operator ==(Nully n, object o)
{
Console.WriteLine("Comparing '" + n + "' with '" + o + "'");
return true;
}
public static bool operator !=(Nully n, object o) { return !(n==o); }
}
void Main()
{
var data = new Nully();
Console.WriteLine(null == data);
Console.WriteLine(object.ReferenceEquals(null, data));
}
Produces:
Comparing '' with 'Nully'
True
False
As of C# 9 you can do
if (obj is null) { ... }
For not null use
if (obj is not null) { ... }
If you need to override this behaviour use == and != accordingly.
No, you should be using !=. If data is actually null then your program will just crash with a NullReferenceException as a result of attempting to call the Equals method on null. Also realize that, if you specifically want to check for reference equality, you should use the Object.ReferenceEquals method as you never know how Equals has been implemented.
Your program is crashing because dataList is null as you never initialize it.
The problem in this case is not that data is null. It is that dataList itself is null.
In the place where you declare dataList you should create a new List object and assign it to the variable.
List<object> dataList = new List<object>();
With c#9 (2020) you can now check a parameter is null with this code:
if (name is null) { }
if (name is not null) { }
You can have more information here
As of C# 8 you can use the 'empty' property pattern (with pattern matching) to ensure an object is not null:
if (obj is { })
{
// 'obj' is not null here
}
This approach means "if the object references an instance of something" (i.e. it's not null).
You can think of this as the opposite of: if (obj is null).... which will return true when the object does not reference an instance of something.
For more info on patterns in C# 8.0 read here.
In addition to #Jose Ortega answer,
its better for use extension method
public static bool IsNull(this object T)
{
return T == null;
}
And use IsNull method for all of object like:
object foo = new object(); //or any object from any class
if (foo.IsNull())
{
// blah blah //
}
Jeffrey L Whitledge is right. Your `dataList´-Object itself is null.
There is also another problem with your code: You are using the ref-keyword, which means the argument data cannot be null! The MSDN says:
An argument passed to a ref parameter must first be initialized. This differs from out, whose arguments do not have to be explicitly initialized before they are passed
It's also not a good idea to use generics with the type `Object´. Generics should avoid boxing/unboxing and also ensure type safety. If you want a common type make your method generic. Finally your code should look like this:
public class Foo<T> where T : MyTypeOrInterface {
public List<T> dataList = new List<T>();
public bool AddData(ref T data) {
bool success = false;
try {
dataList.Add(data);
success = doOtherStuff(data);
} catch (Exception e) {
throw new Exception(e.ToString());
}
return success;
}
private bool doOtherStuff(T data) {
//...
}
}
As others have already pointed out, it's not data but rather likely dataList that is null. In addition to that...
catch-throw is an antipattern that almost always makes me want to throw up every time that I see it. Imagine that something goes wrong deep in something that doOtherStuff() calls. All you get back is an Exception object, thrown at the throw in AddData(). No stack trace, no call information, no state, nothing at all to indicate the real source of the problem, unless you go in and switch your debugger to break on exception thrown rather than exception unhandled. If you are catching an exception and just re-throwing it in any way, particularly if the code in the try block is in any way nontrivial, do yourself (and your colleagues, present and future) a favor and throw out the entire try-catch block. Granted, throw; is better than the alternatives, but you are still giving yourself (or whoever else is trying to fix a bug in the code) completely unnecessary headaches. This is not to say that try-catch-throw is necessarily evil per se, as long as you do something relevant with the exception object that was thrown inside the catch block.
Then there's the potential problems of catching Exception in the first place, but that's another matter, particularly since in this particular case you throw an exception.
Another thing that strikes me as more than a little dangerous is that data could potentially change value during the execution of the function, since you are passing by reference. So the null check might pass but before the code gets to doing anything with the value, it's changed - perhaps to null. I'm not positive if this is a concern or not (it might not be), but it seems worth watching out for.
public static bool isnull(object T)
{
return T == null ? true : false;
}
use:
isnull(object.check.it)
Conditional use:
isnull(object.check.it) ? DoWhenItsTrue : DoWhenItsFalse;
Update (another way) updated 08/31/2017 and 01/25/2021. Thanks for the comment.
public static bool IsNull(object T)
{
return (bool)T ? true : false;
}
Demostration
And for the records, you have my code on Github, go check it out:
https://github.com/j0rt3g4/ValidateNull
PS: This one is especially for you Chayim Friedman, don't use beta software assuming that is all true. Wait for final versions or use your own environment to test, before assuming true beta software without any sort of documentation or demonstration from your end.
Whenever you are creating objects of class you have to check the whether the object is null or not using the below code.
Example:
object1 is object of class
void myFunction(object1)
{
if(object1!=null)
{
object1.value1 //If we miss the null check then here we get the Null Reference exception
}
}
There is a one-liner in .NET 6
ExampleMethod(null);
void ExampleMethod(object param)
{
ArgumentNullException.ThrowIfNull(param);
// Do something
}
I just followed a method that we would usually follow in java script. To convert object to string and then check whether they are null.
var obj = new Object();
var objStr = obj.ToString();
if (!string.IsNullOrEmpty(objStr)){
// code as per your needs
}
I did more simple (positive way) and it seems to work well.
Since any kind of "object" is at least an object
if (MyObj is Object)
{
//Do something .... for example:
if (MyObj is Button)
MyObj.Enabled = true;
}
You can try like below
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
if (data != null)
{
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
Here are some extensions I use:
/// <summary>
/// Extensions to the object class
/// </summary>
public static class ObjectExtensions
{
/// <summary>
/// True if the object is null, else false
/// </summary>
public static bool IsNull(this object input) => input is null;
/// <summary>
/// False if the object is null, else true
/// </summary>
public static bool NotNull(this object input) => !IsNull(input);
}
public bool IsVisible(object ClaimCount)
{
bool flag = true;
#region || HIDE COLUMNS ON CONDITION BASIS
if (!String.IsNullOrEmpty(Convert.ToString(ClaimCount)))
{
Int32 ClaimCnt = Convert.ToInt32(ClaimCount);
if (ClaimCnt == 1)
{
flag = false;
}
}
#endregion
return flag;
}

Categories