• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

            c# class 實現 () (很好)

            Introduction

            While implementing my first projects using C# I found out that there were several issues to take into account if I wanted my classes to behave correctly and make good friends with .NET. This list is more about the "hows" and the "whats" and not the "whys" and while it is in no way complete, it contains the guidelines that I currently follow. Ah, and I almost forgot... it's guaranteed to be incomplete!

            The Guidelines

            1. ImplementIComparable.CompareTo() if ordering of objects makes sense. Also implement operators <, <=, > and >= in terms of IComparable.CompareTo().
              int IComparable.CompareTo(object obj)
              { 
                  return m_data - ((MyType)obj).m_data; 
              } 
              
              publicstaticbooloperator<(MyType lhs, MyType rhs)
              { 
                  return ((IComparable)lhs).CompareTo(rhs) < 0;
              }
              
              publicstaticbooloperator<=(MyType lhs, MyType rhs)
              { 
                  return ((IComparable)lhs).CompareTo(rhs) <= 0;
              }
              
              publicstaticbooloperator>(MyType lhs, MyType rhs)
              { 
                  return ((IComparable)lhs).CompareTo(rhs) > 0;
              }
              
              publicstaticbooloperator>=(MyType lhs, MyType rhs)
              { 
                  return ((IComparable)lhs).CompareTo(rhs) >= 0;
              }
              						
            2. Implement conversion functions only if they actually make sense. Make conversions explicit if the conversion might fail (throw an exception) or if the conversion shouldn’t be abused and it’s only necessary for low level code. Only make conversions implicit if it makes the code clear and easier to use and the conversion cannot fail.
              private MyType(int data)
              { 
                  m_data = data;
              }
              
              publicstaticexplicitoperatorMyType(int from)
              { 
                  returnnew MyType(from);
              }
              
              publicstaticimplicitoperatorint(MyType from)
              { 
                  return from.m_data;
              }
              						
            3. Always implement Object.ToString() to return a significant textual representation.
              publicoverridestring ToString()
              { 
                  returnstring.Format("MyType: {0}", m_data);
              }
              						
            4. Implement Object.GetHashCode() and Object.Equals()if object equality makes sense. If two objects are equal (Object.Equals() returns true) they should return the same hash code and this value should be immutable during the whole lifecycle of the object. The primary key is usually a good hash code for database objects.
              For reference types implement operators == and != in terms of Object.Equals().
              publicoverrideintGetHashCode()
              { 
                  return m_data.GetHashCode();
              }
              
              publicoverrideboolEquals(object obj)
              { 
                  
              // Call base.Equals() only if this class derives from a 
              // class that overrides Equals()
              if(!base.Equals(obj)) returnfalse; if(obj == null) returnfalse; // Make sure the cast that follows won't failif(this.GetType() != obj.GetType()) returnfalse; // Call this if m_data is a value type MyType rhs = (MyType) obj; return m_data.Equals(rhs.m_data); // Call this if m_data is a reference type//return Object.Equals(m_data, rhs.m_data); } publicstaticbooloperator==(MyType lhs, MyType rhs) { if(lhs == null) returnfalse; return lhs.Equals(rhs); } publicstaticbooloperator!=(MyType lhs, MyType rhs) { return !(lhs == rhs); }
            5. For value types, implement Object.Equals() in terms of a type-safe version of Equals() to avoid unnecessary boxing and unboxing.
              publicoverrideintGetHashCode()
              { 
                  return m_data.GetHashCode();
              }
              
              publicoverrideboolEquals(object obj)
              { 
                  
              								
              if(!(obj is MyType))
                      returnfalse;
              
                  returnthis.Equals((MyType) obj);
              }
              
              publicboolEquals(MyType rhs)
              {
                  
              								
              // Call this if m_data is a value type  
              return m_data.Equals(rhs.m_data); // Call this if m_data is a reference type
              //
              return Object.Equals(m_data, rhs.m_data); } publicstaticbooloperator==(MyType lhs, MyType rhs) { return lhs.Equals(rhs); } publicstaticbooloperator!=(MyType lhs, MyType rhs) { return !lhs.Equals(rhs); }
            6. Enumerations that represent bit masks should have the [Flags] attribute.

            7. All classes and public members should be documented using XML comments. Private members should be documented using normal comments. XML comments should at least include <summary>, <param> and <returns> elements.

            8. If a class is just meant to be a "container" for static methods (has no state), it should declare a private parameter-less constructor so it can’t be instantiated.

            9. All classes should be CLS compliant. Add an [assembly:CLSCompliant(true)] attribute in the AssemblyInfo.cs file. If it is convenient to add a non-CLS compliant public member add a [CLSCompliant(false)] attribute to it.

            10. All implementation details should be declared as private members. If other classes in the same assembly need access, then declare them as internal members. Try to expose as little as possible without sacrificing usability.

            11. strings are immutable objects and always create a new copy for all the mutating operations, which makes it inefficient for assembling strings. StringBuilder is a better choice for this task.

            12. object.MemberWiseClone() provides shallow copying. Implement ICloneable to provide deep copy for classes. ICloneable.Clone() is usually implemented in terms of a copy constructor.
              publicMyType(MyType rhs)
              { 
                  m_data = rhs.m_data;
              } 
              
              publicobjectClone()
              { 
                  returnnew MyType(this); //調用拷貝構造函數
              }
              						
            13. If a class represents a collection of objects implement one or more indexers. Indexers are a special kind of property so they can be read-only, write-only or read-write.
              publicobjectthis[int index]
              { 
                 get { return m_data[index]; }set { m_data[index] = value; }
              }
              						
            14. For a "collection" class to be used in a foreach loop it must implementIEnumerable. IEnumerable.GetEnumerator() returns a class the implements IEnumerator.
              publicclass MyCollection: IEnumerable
              { 
                  public IEnumerator GetEnumerator()
                  { 
                      returnnewMyCollectionEnumerator(this);
                  }
              }
              						
            15. The IEnumerator for a "collection" class is usually implemented in a private class. An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying or deleting elements, the enumerator is irrecoverably invalidated and the next call to MoveNext or Reset throws an InvalidOperationException. If the collection is modified between MoveNext and Current, Current will return the element that it is set to, even if the enumerator is already invalidated.
              privateclass MyCollectionEnumerator: IEnumerator
              { 
                  public MyCollectionEnumerator(MyCollection col)
                  { 
                      m_col = col;
                      m_lastChanged = col.LastChanged;
                  } 
              
                  publicboolMoveNext()
                  { 
                      if(m_lastChanged != m_col.LastChanged)
                          thrownew InvalidOperationException();
              
                      if(++m_index >= m_col.Data.Count)
                          returnfalse; 
              
                      returntrue;           
                  }
              
                  publicvoidReset()
                  { 
                      if(m_lastChanged != m_col.LastChanged)
                          thrownew InvalidOperationException();
              
                      m_index = -1;
                  }
              
                  publicobjectCurrent
                  { 
                      get { return m_col.Data[m_index]; } 
                  } 
              }
              						
            16. There is no deterministic destruction in C# (gasp!), which means that the Garbage Collector will eventually destroy the unused objects. When this scenario is not ok, implement IDisposable...
              publicclass MyClass
              {
                  ...
                  public ~MyClass()
                  {
                      Dispose(false);
                  }
              
                  publicvoid Dispose()
                  {
                      
              								
              	 Dispose(true);
                      GC.SuppressFinalize(this);// Finalization is now unnecessary
                  }
                 
                  protectedvirtualvoid Dispose(bool disposing)
                  {
                      
              								
              	if(!m_disposed)
                      {
                          if(disposing)
                          {
                              // Dispose managed resources
                          }
                       
                          // Dispose unmanaged resources
                      }
                    
                      m_disposed = true;
                  }
                 
                  privatebool m_disposed = false;
              }
              
              						
              And use the using statement to dispose resources as soon the object goes out of scope
              using(MyClass c = new MyClass())
              {
                  ...
              } // The compiler will call Dispose() on c here
            17. There is no way to avoid exceptions handling in .NET. There are several strategies when dealing with exceptions:

              • Catch the exception and absorb it
                try
                {
                    ...
                }
                catch(Exception ex)
                {
                    Console.WriteLine("Opps! Something failed: {0}", ex.Message);
                }
                										
              • Ignore the exception and let the caller deal with it if there's no reasonable thing to do.
                publicvoid DivByZero()
                {
                    int x = 1 / 0; // Our caller better be ready to deal with this!
                }
                										
              • Catch the exception, cleanup and re-throw
                try
                {
                    ...
                }
                catch(Exception ex)
                {
                    // do some cleanupthrow;
                }
                										
              • Catch the exception, add information and re-throw
                try
                {
                    ...
                }
                catch(Exception ex)
                {
                    thrownew Exception("Something really bad happened!", ex);
                }
                										
            18. When catching exceptions, always try to catch the most specific type that you can handle.
              try
              {
                  int i = 1 / 0;
              }
              catch(DivideByZeroException ex) // Instead of catch(Exception ex)
              {
                  ...
              }
              
              						
            19. If you need to define your own exceptions, derive from System.ApplicationException, not from System.Exception.

            20. Microsoft's FxCop design diagnostic tool is your friend. Use it regularly to validate your assemblies.

            21. The definite guide for .NET class library designers is .NET Framework Design Guidelines .

            posted on 2006-03-15 17:02 夢在天涯 閱讀(893) 評論(0)  編輯 收藏 引用 所屬分類: C#/.NET

            公告

            EMail:itech001#126.com

            導航

            統計

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1808095
            • 排名 - 5

            最新評論

            閱讀排行榜

            天天久久狠狠色综合| 精品无码久久久久久久动漫| 日韩精品久久久肉伦网站| av午夜福利一片免费看久久| 99久久精品国产毛片| 精品久久久久成人码免费动漫| 99久久精品午夜一区二区| 久久精品国产亚洲7777| 激情伊人五月天久久综合| 欧美久久亚洲精品| 久久91精品国产91久久麻豆| 2021国内精品久久久久久影院| 久久精品人人槡人妻人人玩AV| 少妇久久久久久被弄到高潮| 国内精品人妻无码久久久影院| 久久噜噜久久久精品66| 高清免费久久午夜精品| 人妻无码精品久久亚瑟影视 | 国产精品一区二区久久精品无码| 欧美大战日韩91综合一区婷婷久久青草| 久久久久亚洲av无码专区| 亚洲精品乱码久久久久久蜜桃| 四虎国产精品免费久久5151| 高清免费久久午夜精品| 久久99国产乱子伦精品免费| 亚洲va久久久噜噜噜久久天堂| 午夜视频久久久久一区| 热re99久久精品国产99热| 色噜噜狠狠先锋影音久久| 精品久久久噜噜噜久久久| 久久精品午夜一区二区福利| 亚洲乱码中文字幕久久孕妇黑人| 久久综合亚洲鲁鲁五月天| 亚洲中文字幕无码一久久区| 亚洲中文精品久久久久久不卡| 久久人做人爽一区二区三区| 久久久久av无码免费网| 无码国产69精品久久久久网站| 久久国产精品77777| 欧美伊香蕉久久综合类网站| 国产高潮久久免费观看|