views:

35

answers:

2

Hi, I'm having trouble trying to implement a shared method/property between two classes created by the linq2sql designer.

My two classes have two main properties (coming from the db model):

public partial class DirectorPoll
{
    public bool Completed {get; set;}
    public bool? Reopen { get; set; }
    //more properties
}

public partial class StudentPoll
{
    public bool Completed {get; set;}
    public bool? Reopen { get; set; }
    //more properties
}

Now for example I create an abstract class:

public abstract class GenericPoll
{
    public abstract bool Completed { get; set; }
    public abstract bool? Reopen { get; set; }

    public bool CanEdit
    {
        get
        {
            if (Completed == false) return true;
            if (Reopen.GetValueOrDefault(false) == false) return false;
            return true;
        }
    }
}

Then

public partial class DirectorPoll : GenericPoll
public partial class StudentPoll: GenericPoll

But when I try to compile it says "Director does not implement inherited abstract member GenericPoll.Completed.get". But it is there. So I think I'm forced to put an override to the property automatically generated by the designer, but if I update the database later and recompile it will give me the same error.

I think I might be missing something here but I've tried different approaches with no success. ¿So what can I do here, besides implementing CanEdit in each of my partial classes? Thanks

+2  A: 

One option: create an interface containing Completed and Reopen, make the classes implement the interface (via the manual bits of the partial classes), then write an extension method which extends that interface. I think that should work:

public interface IPoll
{
    bool Completed {get; set;}
    bool? Reopen { get; set; }
}

// Actual implementations are in the generated classes;
// no need to provide any actual code. We're just telling the compiler
// that we happen to have noticed the two classes implement the interface
public partial class DirectorPoll : IPoll {}
public partial class StudentPoll : IPoll {}

// Any common behaviour can go in here.
public static class PollExtensions
{
    public static bool CanEdit(this IPoll poll)
    {
        return !poll.Completed || poll.Reopen.GetValueOrDefault(false);
    }
}

Admittedly then it has to be a method rather than a property, as there's no such thing as an extension property, but that's not too much of a hardship.

(I believe my refactoring of your logic in CanEdit is correct. All those explicit trues and falses were doing my head in ;)

Jon Skeet
lol; I love how we both fought the yucky `return` ;p Your `!` is misplaced, btw.
Marc Gravell
@Marc: Doh - that would be due to forgetting to include `poll` first time :)
Jon Skeet
I noticed that too; I was too busy simplifying to comment ;p
Marc Gravell
Sorry for explicit bool comparisons, sometimes it helps me to understand program flow when I sleep less ^^
Francisco
@Fransisco - if it is simpler to understand, then fine - but to the outside observer it is "count the negatives" time ;p
Marc Gravell
+2  A: 

It isn't implemented as an override, so it doesn't count. However, implicit interface implementations do count, so this works:

partial class DirectorPoll : IGenericPoll {}
partial class StudentPoll : IGenericPoll {}
public interface IGenericPoll
{
    bool Completed { get; set; }
    bool? Reopen { get; set; }
}
public static class GenericPoll {
    public static bool CanEdit(this IGenericPoll instance)
    {
        return !instance.Completed || instance.Reopen.GetValueOrDefault();
    }
}
Marc Gravell
We are Borg of Graveet. Fear us.
Jon Skeet
Nice =)Thanks to both!
Francisco