C#嵌套类/结构可见性

时间:2011-06-30 18:13:10

标签: c# class syntax struct nested

我正在试图弄清楚实现某个API目标的正确语法是什么,但是我在努力实现可见性。

我希望能够像Messenger一样访问msgr.Title.ForSuccesses实例的成员。

但是,我不希望能够从Messenger.Titles课程外部实例化Messenger

我也愿意将Messenger.Titles变成一个结构。

我猜我需要某种工厂模式或某种东西,但我真的不知道我该怎么做。

见下文:

class Program {
    static void Main(string[] args) {
        var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this should be allowed
        var t = new Messenger.Titles(); // this should NOT be allowed
    }
}

public class Messenger {
    // I've tried making this private/protected/internal...
    public class Titles {
        public string ForSuccesses { get; set; }
        public string ForNotifications { get; set; }
        public string ForWarnings { get; set; }
        public string ForErrors { get; set; }

        // I've tried making this private/protected/internal as well...
        public Titles() {}
    }

    public Titles Title { get; private set; }
    public Messenger() {
        Title = new Titles();
    }
}

4 个答案:

答案 0 :(得分:7)

你只需要将标题设为私有并公开界面而不是它。


class Program {
    static void Main(string[] args) {
        var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this is allowed
        var t = new Messenger.Titles(); // this is NOT allowed
    }
}

public class Messenger {
    public interface ITitles {
        string ForSuccesses { get; set; }
        string ForNotifications { get; set; }
        string ForWarnings { get; set; }
        string ForErrors { get; set; }
    }

    private class Titles : ITitles {
        public string ForSuccesses { get; set; }
        public string ForNotifications { get; set; }
        public string ForWarnings { get; set; }
        public string ForErrors { get; set; }
    }

    public ITitles Title { get; private set; }
    public Messenger() {
        Title = new Titles();
    }
}

答案 1 :(得分:0)

如果您创建Titles构造函数internal,您将只能在程序集中创建它的实例。如果它是一个API,也许这将受到足够的保护?您可以在BCL中看到此模式(例如只能通过调用HttpWebRequest创建的WebRequest.Create)。

答案 2 :(得分:0)

Why Would I Ever Need to Use C# Nested Classes嵌套类型永远不会从外部类型初始化。

答案 3 :(得分:0)

好吧,你可以使标题成为一个结构,并使构造函数公开或内部。这样,每当客户端通过Title属性获取Titles实例的副本时,他们将获得值,而不是引用。他们可以修改该值,但是要将该更改应用于对象的内部状态,他们需要能够通过Title属性再次设置该值。他们不能,因为你将Title setter标记为private。

在内部更改值时,您必须执行相同的操作。例如:

// Your constructor...
public Messenger()
{
    Titles t = new Titles();
    t.ForSuccesses = "blah";
    Title = t;
}

您可以在内部执行此操作,因为您可以访问Title属性的私有设置器。

主要的缺点是它可能会混淆框架的客户端,因为看起来你可以设置Titles实例的值,但是没有真正的方法让他们将更改提交回Messenger类。