Francisco
Francisco

Reputation: 4101

Abstract class in LINQ2SQL for sharing common methods

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

Upvotes: 1

Views: 136

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500575

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 ;)

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1062820

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();
    }
}

Upvotes: 2

Related Questions