c# - 防止两个接口(interface)之间的转换

标签 c# .net interface polymorphism implementation

我有一个内部类,其中包含实现细节,包括属性,这些细节不应公开访问。我必须将这个类传递给公共(public)调用者,并允许他们传递它、存储它、序列化它,或者基本上用它做任何他们想做的事情。该类可以通过两种不同的方式公开访问。这些方式作为两个公共(public)接口(interface)公开。我想阻止用户在两个公共(public)接口(interface)之间进行转换。这是一些代码来演示我正在谈论的内容。

void Main()
{
    var container = new ContainsDetails(5);

    Console.WriteLine(container.LessDetail.TheDetails);
    var more = (ContainsDetails.IFooPlus)(container.LessDetail);
    more.TheDetails = 10;
    Console.WriteLine(container.LessDetail.TheDetails);
}

public class ContainsDetails {
    public interface IFooPlus {
        int TheDetails {
            get;
            set;
        }
    }

    public interface IFoo {
        int TheDetails {
            get;
        }
    }

    private readonly Detail _myDetail;

    public ContainsDetails(int x) {
        _myDetail = new Detail(x);
    }

    public IFoo LessDetail {
        get {
            return _myDetail;
        }
    }

    public IFooPlus MoreDetail {
        get {
            return _myDetail;
        }
    }

    public bool ProcessFoo(IFoo foo) {
        var theDeets = foo as Detail;
        if (theDeets != null) {
            return theDeets.TheDetails++%2 == 0;
        } else {
            throw new ArgumentException("foo argument must have originated from ContainsDetails.");
        }
    }

    private class Detail : IFooPlus, IFoo {
        private int _myX;

        private Detail() {}

        internal Detail(int x) {
            _myX = x;
        }

        public int TheDetails {
            get {return  _myX; }
            set { _myX = value; }
        }
    }
}

输出是:

5
10

我希望上面的输出是:

5
System.InvalidCastException thrown.....

类(class)ContainsDetails只是为了演示。在我的实际代码中,程序集扮演 ContainsDetails 的角色。同样,Detailinternal我的实际代码中的类。

在这里,用户知道 IFooPlusIFoo 。用户不知道Detail存在。用户也不知道 LessDetail 返回的对象可转换为IFooPlus 。我的代码返回相同的 Detail在不同时间向用户发出对象,并将其返回为 IFooIFooPlus取决于Detail的一些复杂状态和其他内部对象。另请注意 ProcessFoo ContainsDetails中的方法。我的代码需要能够接受 IFoo来自用户,并将其处理为 Detail

我想要 Actor var more = (ContainsDetails.IFooPlus)(container.LessDetail)生成 InvalidCastException 。对所有 IFooPlus 进行运行时检查的成本过高。操作来确定 Detail 是否对象对于这些操作处于正确的状态。相反,我希望用户永远无法处理 IFoo作为IFooPlus .

我能想到的唯一选择是嵌入一些 IFoo Detail 内的成员子类并有 Detail子类之间保存着彼此的引用。恶心。

是否有防止这种类型转换的最佳实践,或者我应该附上 IFoo Detail 的成员子类中的功能?

最佳答案

最简单的方法是使用一个只读包装器,它具有对可写包装器的引用。因此,LessDetail 将始终返回相同的包装器引用,但 MoreDetail 将返回对“真实”类型的引用。然后,您可以使它们都实现一个内部接口(interface),该接口(interface)允许您执行所需的任何操作,而包装器可能会将这些调用代理到底层对象。

或者,您可以尝试重新审视您的设计 - 目前听起来并不理想,要么无法在类型之间进行转换,要么 ProcessFoo 接受 编译时的任何 IFoo,但实际上只能处理一种特定的实现。对我来说,这感觉就像是滥用继承权。

关于c# - 防止两个接口(interface)之间的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11389900/

相关文章:

c# - 如何在程序运行时创建列表

java - 如何获取从具有指定泛型的接口(interface)继承的所有类的列表(接口(interface)<具体类>)

java - 匿名类重写与传递接口(interface),用于在 Java 中设计回调

c# - 如何使 ASP.NET Core Web API 操作异步执行?

c# - DataObject.GetData() 无论如何都会返回 MemoryStream 类型的对象?

c# - 如何在 C# 中生成随机深色?

c# - 将类的属性绑定(bind)到 WPF 按钮

javascript - ckeditor 中的 Chrome 拖放问题

java - 为什么要将 Java 接口(interface)方法声明为抽象的?

c# - "Generate Debug Info"在 VB/C# 中是什么意思?