嵌套属性/类

时间:2014-06-12 06:20:58

标签: c#

我希望能够拥有一个具有属性的类,但是有一些方法可以使用"命名空间"属性。

最后我想上课:

Class Employee
{
    public string Name {get; set;}

    private class/namespace/something HomeAddress
    {
        public string Street {get; set;}
    }
}

我希望能够去:

Employee emp = new Employee();
emp.Name = "Joe";
emp.HomeAddress.Street = "Best St.";

这甚至可能吗? (或者最佳实践,对于类似的东西,最佳实践是什么?)我知道我可以创建单独的类,在Employee Constructor中初始化它们并从那里开始......

但我想隐藏嵌套类,因为它们只会在Employee类中使用。我想避免这样做:

HomeAddress home = new HomeAddress();
home.Street = "Worst St.";

我想将它隐藏在intellisense列表中,并且没有它可以自己创建,因此只有Employee类对于某人来说是可见的,因为这些辅助类只会在其他对象中使用永远不要靠自己。

另一个问题还有另一个例子:

class Fruit{
    public void eat(){
        MessageBox.Show("Fruit eaten");
    }
    public string color = "red";
    //you have declared the class but you havent used this class
    public class physicalProperties{
        public int height = 3;

    }
    //create a property here of type PhysicalProperties
    public physicalProperties physical;
}

但是,由于physicalProperties是公开的,所以这并不是我所追求的。你仍然可以:

Fruit.physicalProperties fruitProp = new Fruit.physicalProperties();

在Fruit课程之外使用它。

我有一种感觉,我正在追逐一些我永远无法找到的东西,但我很好奇是否还有其他人需要做这样的事情?看来当你构建一个应用程序时,你最终会在intellisense列表中找到大量的对象,其中一些是地雷,因为如果有人看到HomeAddress,他们可能认为它对某些东西很有用。如果只有员工出现在intellisense列表中,那么他们将从一开始就处于正确的轨道上,创建Employee对象,然后修改与该员工相关的所有内容。

将所有支持垃圾放在与您应该使用的主要对象相同的智能感知列表中似乎会增加噪音和分心,特别是如果编码人员不熟悉您的库。在我看来,这种方式将是一个微妙的指导,你应该创建什么,一旦你创建它应该如何操纵它...

3 个答案:

答案 0 :(得分:2)

为防止创建地址,我会执行以下操作。接口是公共的,但实现嵌套类是私有的。

public class Employee {
    #region Constructor(s)

    public Employee() {
        HomeAddress = new Address();
    }

    #endregion
    #region Properties

    public string Name { get; set;}
    public IAddress HomeAddress { get; private set; }

    #endregion
    #region Nested

    public interface IAddress {
        string Street { get; set; }
    }

    private class Address: IAddress {
        public string Street { get; set;}
    }

    #endregion
}

在阅读@ Moeri的回答后,您还可以懒惰而不是在构造函数中创建实例。

答案 1 :(得分:1)

如何在Employee类中嵌套Address类并在需要时自动初始化它。

public class Employee
{
    public string Name {get; set;}

    private Address _homeAddress;

    // only contains a getter, which auto-initializes the value to avoid NullReferenceException
            // this auto initialization is also useful to declutter your constructors
    public Address HomeAddress
    {
        get { return _homeAddress ?? (_homeAddress = new Address()); }
    }

    public class Address
    {
        // only classes from the same assembly can create addresses
        internal Address() {}

        public string Street {get; set;}
    }
}

答案 2 :(得分:1)

如果没有为每个嵌套级别指定类型,则不能拥有“嵌套属性”。此外,呼叫者(公共)必须能够访问每个级别的类型。

但你可以避免这个需要:

HomeAddress home = new HomeAddress();
home.Street = "Worst St.";

通过在HomeAddress构造函数中创建新的Employee

public Employee()
{
    this.HomeAddress = new HomeAddress();
}

public HomeAddress HomeAddress
{
    get;
    private set;
}

没有人可以为该属性分配 HomeAddress,但他们可以更改HomeAddress的值。

要记住的另一件事是,如果您有嵌套的 Employee.HomeAddress,则该属性的名称不能相同。