C#避免重复接口属性的代码

时间:2016-07-01 13:09:03

标签: c# class interface repeat

鉴于界面:

interface IVotable
{
    int TotalUpvotes { get; }
    int TotalDownvotes { get; }
    int TotalVoteScore { get; }
}

实施:

public class Comment : IVotable
{
    public int TotalUpvotes { get; private set; }
    public int TotalDownvotes { get; private set; }
    public int TotalVoteScore { get { return TotalUpvotes - TotalDownvotes + 1 ; } }
}

避免在每个班级以相同的方式实施TotalVoteScore的最佳方法是什么?

5 个答案:

答案 0 :(得分:4)

如果TotalVoteScore始终以与IVotable上的扩展方法相同的方式进行计算:

public static int TotalVoteScore(this IVotable v) {
    return v.TotalUpvotes - v.TotalDownvotes + 1
}

答案 1 :(得分:4)

如果只有TotalVoteScore您不想重新实施,那么这就是要走的路:

public interface IVotable
{
    int TotalUpvotes { get; }
    int TotalDownvotes { get; }
    int TotalVoteScore { get; }
}

public abstract class VotableBase : IVotable
{
    public abstract int TotalUpvotes { get; protected set; }
    public abstract int TotalDownvotes { get; protected set; }
    public virtual int TotalVoteScore { get { return TotalUpvotes - TotalDownvotes + 1 ; } }
}

public class Comment : VotableBase
{
    public override int TotalUpvotes { get; protected set; }
    public override int TotalDownvotes { get; protected set; }
}

答案 2 :(得分:3)

如果你想要一个像接口这样的东西(一个说明必须有一些带有指定签名的方法的合同)和公共代码相结合,我想这个解决方案是一个抽象类:

public abstract class Votable
{
    public abstract int TotalUpvotes { get; protected set; }
    public abstract int TotalDownvotes { get; protected set; }
    public virtual int TotalVoteScore { get { return TotalUpvotes - TotalDownvotes + 1; } }
}

并从该类派生:

public class Comment : Votable
{
    public override int TotalUpvotes { get; protected set; }
    public override int TotalDownvotes { get; protected set; }
}

答案 3 :(得分:3)

public abstract class VotableBase
{
    public int TotalUpvotes { get; protected set;}
    public int TotalDownvotes { get; protected set; }
    public int TotalVoteScore { get { return TotalUpvotes - TotalDownvotes + 1 ; } }
}

那么你的派生类不需要任何实现 - 它已经继承了属性:

public class Comment : VotableBase
{
    public void DoThings()
    {
        //e.g.
        Console.WriteLine(TotalVoteScore);
    }
}

答案 4 :(得分:0)

将组合物方法投入混合物中。我根本不反对遗产。但这对我来说是一个不使用它的好例子。为什么限制这个类只能导出投票功能?我可以想象这个班级有很多东西与一个"评论"例如作者信息(排名,生物,头像),格式,年龄,编辑历史等。其中一些似乎更适合作为基类。

public interface IVotable
{
    int TotalUpvotes { get; }
    int TotalDownvotes { get; }
    int TotalVoteScore { get; }
}

// shared implementation
public class VoteStatus : IVotable
{
    public int TotalUpvotes { get; private set; }
    public int TotalDownvotes { get; private set; }
    public int TotalVoteScore { get { return TotalUpvotes - TotalDownvotes + 1; } }
}

// has A...
public class Comment : IVotable
{
    // expose it?
    public IVotable VoteStatus { get; private set; }

    // allow current vote status to be injected?
    public Comment(IVotable voteStatusReference)
    {
        this.VoteStatus = voteStatusReference;
    }

    // or don't use injection?
    public Comment()
        : this(new VoteStatus())
    {
    }

    public int TotalUpvotes => this.VoteStatus.TotalUpvotes;
    public int TotalDownvotes => this.VoteStatus.TotalDownvotes;
    public int TotalVoteScore => this.VoteStatus.TotalVoteScore;
}

注意:我觉得扩展方法建议也比继承更好。