Author Topic: Anyone using Code Contracts?  (Read 3515 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Anyone using Code Contracts?
« on: July 14, 2012, 08:58:29 PM »
Was wondering if anyone was using code contracts?
useless example
Code - C#: [Select]
  1.             public static void SETWIPEOUTFRAME (this Database db, int value)
  2.             {
  3.                 Contract.Requires<ArgumentOutOfRangeException>(value >= 0 && value <= 2);
  4.                 Application.SetSystemVariable("WIPEOUTFRAME", value);
  5.             }
  6.  

The base Library uses them for example ICollection<T> count method must return 0 or greater
The code below will give error
Quote
An unhandled exception of type 'System.Diagnostics.Contracts.__ContractsRuntime.ContractException' occurred in ConsoleApplication1.exe
Additional information: Postcondition failed: Contract.Result<int>() >= 0
Code - C#: [Select]
  1. class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             FailPostCondition<int> fail = new FailPostCondition<int>();
  6.             Console.WriteLine(fail.Count);
  7.             Console.ReadLine();
  8.         }
  9.     }
  10.  
  11.     public class FailPostCondition<T> : ICollection<T>
  12.     {
  13.         public void Add(T item){}
  14.         public void Clear(){}
  15.         public bool Contains(T item) {return true;}
  16.         public void CopyTo(T[] array, int arrayIndex){}
  17.         public bool IsReadOnly { get { return true; } }
  18.         public bool Remove(T item) { return true; }
  19.         public IEnumerator<T> GetEnumerator() { return this.GetEnumerator(); }
  20.         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  21.         {
  22.             List<int> ints = new List<int>();
  23.             return ints.GetEnumerator();
  24.         }
  25.  
  26.         public int Count
  27.         {
  28.             get { return -1; }
  29.         }
  30.     }
  31.  
LINK
 
MSDN documentation.
 
Have to download add-in at DEVLABS  to set properties
 

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8718
  • AKA Daniel
Re: Anyone using Code Contracts?
« Reply #1 on: July 14, 2012, 11:10:44 PM »
Not quite a user friendly exception message  :|
Whats the performence hit for the runtime checking?

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Anyone using Code Contracts?
« Reply #2 on: July 14, 2012, 11:22:41 PM »
Not sure and what I was wondering about, seems the little I read was written by fans of Eiffel Software and wanted a .NET equivelent of 'Design by Contract', and tried to cover what they thought were the good parts.
There is a PDF on download site that goes in to some detail but just skimmed through it.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Anyone using Code Contracts?
« Reply #3 on: February 24, 2013, 01:11:19 PM »
To revisit this.
Seems like this might be useful for forcing requirements you want to implement.

You do take some performance hits but,
do you guys think it would be useful or good practice to use contracts only for debug build and removed for release build?

I was not thinking to use them for any logic responsible for checking user input or null checks etc...., but maybe something like routines you want to require a transaction to be active.
On the other hand just checking if the TopTransaction is null probably does not use many cycles.

Just threw it in somewhere and come to think of it, since it is a extension method for type derived from DBObject I would hope there was a transaction open anyway.
Code - C#: [Select]
  1.        public static IEnumerable<T> GetEntries<T>(this DBDictionary dic, OpenMode mode = OpenMode.ForRead, bool openErased = false) where T : DBObject
  2.        {
  3.            if (dic == null)
  4.            {
  5.                throw new ArgumentNullException("source");
  6.            }
  7.  
  8.  
  9.            Contract.Requires(dic.IsTransactionResident);
  10.            //////OR
  11.            Contract.Requires(dic.Database.TransactionManager.TopTransaction != null);
  12.            //////OR
  13.            Contract.Requires(dic.Database.TransactionManager.NumberOfActiveTransactions > 0);
  14.  
  15.  
  16.            TransactionManager tm = dic.Database.TransactionManager;
  17.                          
  18.            foreach (var entry in openErased ? dic.IncludingErased : dic)
  19.            {
  20.                yield return (T)tm.GetObject(entry.Value, mode, openErased, false);
  21.            }
  22.        }

TheMaster

  • Guest
Re: Anyone using Code Contracts?
« Reply #4 on: February 24, 2013, 09:43:22 PM »
To revisit this.
Seems like this might be useful for forcing requirements you want to implement.

You do take some performance hits but,
do you guys think it would be useful or good practice to use contracts only for debug build and removed for release build?

I was not thinking to use them for any logic responsible for checking user input or null checks etc...., but maybe something like routines you want to require a transaction to be active.
On the other hand just checking if the TopTransaction is null probably does not use many cycles.

Just threw it in somewhere and come to think of it, since it is a extension method for type derived from DBObject I would hope there was a transaction open anyway.
Code - C#: [Select]
  1.        public static IEnumerable<T> GetEntries<T>(this DBDictionary dic, OpenMode mode = OpenMode.ForRead, bool openErased = false) where T : DBObject
  2.        {
  3.            if (dic == null)
  4.            {
  5.                throw new ArgumentNullException("source");
  6.            }
  7.  
  8.  
  9.            Contract.Requires(dic.IsTransactionResident);
  10.            //////OR
  11.            Contract.Requires(dic.Database.TransactionManager.TopTransaction != null);
  12.            //////OR
  13.            Contract.Requires(dic.Database.TransactionManager.NumberOfActiveTransactions > 0);
  14.  
  15.  
  16.            TransactionManager tm = dic.Database.TransactionManager;
  17.                          
  18.            foreach (var entry in openErased ? dic.IncludingErased : dic)
  19.            {
  20.                yield return (T)tm.GetObject(entry.Value, mode, openErased, false);
  21.            }
  22.        }

The code I used for runtime checks like that one has been around longer than code contracts and most was written while .NET 2.0 was current, so I've not migrated to them, but they're similar to the framework classes.

I routinely use a very simple class called 'Assert' with members like IsNotNull(), IsNotNullOrEmpty(), IsTrue(), IsFalse(), etc... I could have them delegate to the framework equivalent APIs too, but haven't bothered since they working just fine.

In my Linq libraries, the check for an active transaction is done implicitly by a call to a method called GetTransaction(), which is overloaded to take a DBObject, ObjectId, IEnumerable, etc... They return the top transaction or throw an exception if no transactions are active.

The major problem I've been trying to figure out how to solve without major surgery, is how to support both OpenCloseTransactions and regular old Transactions at the same time. It's not trivial because OpenCloseTransactions aren't really transactions, so for example, in the code you show above, if the object whose IsTransactionResident property was opened with an OpenCloseTransaction, IsTransactionResident will be false.

csharpbird

  • Newt
  • Posts: 64
Re: Anyone using Code Contracts?
« Reply #5 on: February 24, 2013, 10:40:29 PM »
Hi,Tony
Can you provide the Linq libraries? Thanks a lot

TheMaster

  • Guest
Re: Anyone using Code Contracts?
« Reply #6 on: February 24, 2013, 11:03:20 PM »
Hi,Tony
Can you provide the Linq libraries? Thanks a lot

No, sorry I can't. 


Jeff H

  • Needs a day job
  • Posts: 6150
Re: Anyone using Code Contracts?
« Reply #7 on: February 28, 2013, 11:16:30 AM »
Thanks Tony,
and speaking of OpenCloseTransaction you got to love when they do this.
Code - C#: [Select]
  1.     public override TransactionManager TransactionManager
  2.     {
  3.         get
  4.         {
  5.             throw new Exception(ErrorStatus.NotApplicable);
  6.         }
  7.     }


TheMaster

  • Guest
Re: Anyone using Code Contracts?
« Reply #8 on: March 01, 2013, 02:39:56 AM »
Thanks Tony,
and speaking of OpenCloseTransaction you got to love when they do this.
Code - C#: [Select]
  1.     public override TransactionManager TransactionManager
  2.     {
  3.         get
  4.         {
  5.             throw new Exception(ErrorStatus.NotApplicable);
  6.         }
  7.     }

They did that to prevent you from making the mistake of presuming that an OpenCloseTransaction is managed by the TransactionManager, and can be the "Top" transaction, which is never the case. This is my biggest issue with OpenCloseTransaction.

They only exist in managed code, and the TransactionManager and its native counterpart know absolutely nothing about them.