C#中的幂等接口方法

时间:2019-04-30 12:37:44

标签: c# oop interface

我正在尝试创建一个接口,该接口返回实现该实例的修改后的副本,而不修改原始实例。

public interface ICensoreable<T> {
    T GetCensored();
}

以及实现的对象

public class User:ICensoreable<User> {
    public User(User copyFrom) {
        this.name = copyFrom.name;
        this.password = copyFrom.password;
    }

    public string name;
    public string password;

    public User GetCensored() {
        User result = new User(this);
        result.password = null;

        return result;
    }
}

有什么方法可以强制在接口上 GetCensored不会修改用户(或T)实例吗?

1 个答案:

答案 0 :(得分:3)

使用最新版本的C#8.0,您现在可以在界面中定义默认方法实现。因此,您可以强制默认使用GetCensored()方法不修改原始实例。通过将默认实现标记为sealed,禁止实现该接口的类型显式重新实现该方法。由于该方法仅在接口中实现,因此您需要在调用ICensoreable<T>方法之前将对象强制转换为GetCensored()

这是我使用的实现:

public interface ICensoreable<T>
{
    sealed ICensoreable<T> GetCensored()
    {
        var result = Clone();
        result.CensorInformation();
        return result;
    }

    ICensoreable<T> Clone();
    void CensorInformation();
}

public class User : ICensoreable<User>
{
    public User(User other)
    {
        name = other.name;
        password = other.password;
    }

    public string name;
    public string password;

    public void CensorInformation()
    {
        password = null;
    }

    public User Clone() => new User(this);
    ICensoreable<User> ICensoreable<User>.Clone() => Clone();
}

使用GetCensored()方法:

var user = new User();
var censored = ((ICensoreable<User>)user).GetCensored();

注意::在撰写本文时,此实现NullReferenceException方法的第一行中抛出GetCensored()(使用VS 16.4.0 Preview 2.0上的C#8.0)。我个人认为这是一个错误,因为删除sealed关键字不会对完全相同的代码造成任何问题。此外,我尝试了另一种实现,其中涉及初始化一个类型为T的新对象,该对象也崩溃了。该行是var result = new T();,它抛出了NullReferenceException

理论上,按照建议,sealed关键字只是防止类型覆盖接口方法,而仅保留默认实现。

编辑1:当前在VS 16.4.0 Preview 5.0中,引发的异常是AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'。经过一番调查后,我意识到与相关的GitHub issue一起已知的bug已经有几个星期了。根据某人的说法,在后续fix之后,此问题已在16.5.0 Preview 1.0及更高版本中修复。

编辑2:当前在VS 16.5.0 Preview 1.0中,例外仍然是相同的。还没有针对此问题的修复程序。