The object is not referenced to the instance, that is, the NullReferenceException exception. I believe this is one of the most common errors in c # programming. At least this exception will be thrown many times during project creation. Every time this exception occurs, I always stick to my head, because in my experience, this error is generally not reported, but once this error occurs, it is often difficult to troubleshoot, especially when there is a large amount of code, and when a bug is found, there is often a tangle state, because NullReferenceException is often closely linked to the program logic, this means that your program is not wrong, but it is likely that your programming logic is not properly designed.
Of course, the NullReferenceException solution is also very simple, as long as the code similar to the following is added to the exception.
1 if(obj != null)2 {3 //some actions 4 }
This means to check whether the reference is empty before using this reference. But it is not that simple. As mentioned above, NullReferenceException is often related to the code design logic, especially when the code is large, once this error is found, this section of code is often restructured!
More importantly, sometimes in a piece of code, you need to determine whether a reference is null based on different situations, or whether it actually points to a real object. This situation is the most tangled, because it means that the above Code must be added to every place that needs to be referenced!
As a programmer, this is intolerable!
Because a simple if (obj! = Null) the code has been repeated for countless times, and a code with repeated patterns appears in the code. I know this can be seen as a programmer's failure! How to remove if (obj! = Null) What about this mode? Some Daniel once said:
Null should not be used at any time. You should design an empty class to replace null.
As for the "Sin and penalty" of null pointers, I think every programmer has his own opinions. In my opinion, null pointers can be listed as the greatest innovation in programming history, it can also be included in the biggest Evil source!
What is the use of null classes to replace null? Here we use the log Logger class as an example to illustrate (of course, you can use log4net in the actual project or other IOC frameworks to implement logging)
1 public class Logger 2 { 3 private class EmptyLog : Logger 4 { 5 public override void Log(string msg){ } 6 public override void LogErr(string errMsg) { } 7 public override void LogErr(Exception ex) { } 8 } 9 static Logger()10 {11 Empty = new EmptyLog();12 }13 public static Logger Empty { get; private set; }14 15 readonly TextWriter writer;16 private Logger() { }17 public Logger(TextWriter writer)18 {19 this.writer = writer;20 }21 public virtual void Log(string msg)22 {23 writer.WriteLine(DateTime.Now);24 writer.WriteLine(msg);25 writer.WriteLine();26 }27 public virtual void LogErr(string errMsg)28 {29 writer.WriteLine("error");30 Log(errMsg);31 }32 public virtual void LogErr(Exception ex)33 {34 writer.WriteLine(string.Format("error<{0}>",ex.GetType().FullName));35 Log(ex.Message);36 }37 }
The following is the test code and result:
1 [STAThread] 2 static void Main() 3 { 4 var log = Logger.Empty; 5 log.Log("hellow world"); 6 log.LogErr("error"); 7 log.LogErr(new NullReferenceException()); 8 log = new Logger(Console.Out); 9 log.Log("hellow world");10 log.LogErr("this is a error message");11 log.LogErr(new NullReferenceException());12 }
Visible,Null should not be used at any time. You should design an empty class to replace null.This sentence means not to assign null values to a reference, but to point to an empty class example during initialization!
This method is indeed good, at least to avoid if (obj! = Null) This monotonous model, but I think it is still a bit uncomfortable, because that empty class is purely a waste of resources, since there is no need to record logs, so we should point the reference to null to indicate that there is nothing, and this method means that even if you do not do anything, you need to consume some resources to provide this empty class! This unnecessary waste of resources is the same as that of repetition. So I designed a method:
Avoid if (obj! = Null) mode!
The Extension Method and Linq are two of my favorite C # language features. Why is Common Lisp so powerful? It is because programmers can expand the Lisp syntax and customize the syntax they want, similarly, the C # key extension method can also implement the extension syntax function. below is the Logger class I redesigned using the extension method:
1 public class Logger 2 { 3 readonly TextWriter writer; 4 public Logger(TextWriter writer) 5 { 6 this.writer = writer; 7 } 8 internal void Log(string msg) 9 {10 writer.WriteLine(DateTime.Now);11 writer.WriteLine(msg);12 writer.WriteLine();13 }14 internal void LogErr(string errMsg)15 {16 writer.WriteLine("error");17 Log(errMsg);18 }19 internal void LogErr(Exception ex)20 {21 writer.WriteLine(string.Format("error<{0}>",ex.GetType().FullName));22 Log(ex.Message);23 }24 }25 public static class LoggerHelper26 {27 public static void Log(this Logger logger, string msg)28 {29 if (logger != null)30 logger.Log(msg);31 }32 public static void LogErr(this Logger logger, string errMsg)33 {34 if (logger != null)35 logger.LogErr(errMsg);36 }37 public static void LogErr(this Logger logger, Exception ex)38 {39 if (logger != null)40 logger.LogErr(ex);41 }42 }
The following is the test code and result:
1 [STAThread] 2 static void Main() 3 { 4 Logger log = null; 5 log.Log("hellow world"); 6 log.LogErr("error"); 7 log.LogErr(new NullReferenceException()); 8 log = new Logger(Console.Out); 9 log.Log("hellow world");10 log.LogErr("this is a error message");11 log.LogErr(new NullReferenceException());12 }
The test code can be opened, even if the variable log is null, the code can still run normally, because I put if (obj! = Null) the mode is encapsulated using the extension method, so that you can safely use log. Do not worry about whether the log is null or not, and when you do not need to record the log, you can directly assign the log value to null without wasting any resources.
This is my solution for "not referencing objects to instances". If you have other good solutions, please feel free to contact us here!