Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code contracts and inheritance problems, what goes where?

I might be misunderstanding code contracts, but here's my situation.

I have the following code:

interface IFetch<T>    // defined in another DLL
{
    T Fetch(int id);
}

interface IUserFetch : IFetch<User>
{
    IEnumerable<User> GetUsersLoggedIn ();
}

class UserFetch : IUserFetch
{
    public User Fetch(int id)
    {
        return (User) Database.DoStuff (id);
    }

    public IEnumerable<User> GetUsersLoggedIn ()
    {
        return (IEnumerable<User>) Database.DoMoreStuff ();
    }
}

I'm trying to add a relatively simple contract: Contract.Requires (id != 0);, and I want it validated on Fetch. When I add it to Fetch directly, I get the warning that Method Fetch(int id) implements interface 3rdParty.IFetch<User> and thus cannot add Requires.

I created an abstract code contracts class implementing IFetch and pointed it to/from UserFetch using the ContractClass and ContractClassFor attributes respectively. I still get an error like CodeContracts: The class 'FetchUserContracts' is supposed to be a contract class for '3rdParty.IFetch<User>', but that type does not point back to this class. However, since 3rdParty.IFetch is a generic type, I don't think I can ever put a code contract on it specifically.

Has the problem been made clear, and if so, how do I solve it?

like image 619
Bryan Boettcher Avatar asked Jan 12 '12 23:01

Bryan Boettcher


Video Answer


1 Answers

You need to create an abstract class to implement the contract, for example:

[ContractClassFor(typeof(IFetch<>))]
public abstract class ContractClassForIFetch<T> : IFetch<T>
{
    public T Fetch(int id)
    {
        Contract.Requires(id != 0);
        return default(T);
    }
}

And add the following ContractClass attribute to IFetch:

[ContractClass(typeof(ContractClassForIFetch<>))]
public interface IFetch
{
    T Fetch(int id);
}
like image 194
Ɖiamond ǤeezeƦ Avatar answered Sep 23 '22 02:09

Ɖiamond ǤeezeƦ