3

如果我有 3 个班级,可以说:Mainclass、ChildClass、OtherChild。

MainClass()
{
     ChildClass cc = new ChildClass();
     OtherChild oc = new OtherChild();

     //Set the name property of childclass
     string childName = "some name";
}

ChildClass()
{
    public string name {get; set;}
}

OtherChild()
{
     //Here i want to get the name property from ChildClass()
     //Doing this will make a new instance of ChildClass,  which will not have the name property set.
     ChildClass cc = new ChildClass(); 

}

解决方案是什么?

4

5 回答 5

7

基本上,为了从一个类到另一个类访问信息,您必须在实例之间以某种方式“传递”该信息。

这是一个使用基本设置的快速注释示例。我已经包含了一些关于在对象之间发送信息的不同方式的示例:

public MainClass()
{
    // just using auto-properties here. Will need initialized before use.
    public ChildClass cc { get; set; }
    public OtherChild oc { get; set; }

     // Constructor. Gets called when initializing as "new MainClass()"
     public MainClass() 
     {                
        // initialize our properties

        // option 1 - initialize, then set
        cc = new ChildClass();
        cc.childName = "some name"; //Set the name property of childclass

        //option 2 - initialize and set via constructor
        cc = new ChildClass("some name");

        // option 3 - initialize and set with initializer (more here: http://msdn.microsoft.com/en-us/library/vstudio/bb397680.aspx)
        cc = new ChildClass() { name = "some name" };

        oc = new OtherChild(cc);
     }
}

public ChildClass()
{
    public string name { get; set; }

    // Default constructor. this.name will = null after this is run
    public ChildClass() 
    {                
    }

    // Other constructor. this.name = passed in "name" after this is run
    public ChildClass(string name) 
    {
        //"this.name" specifies that you are referring to the name that belongs to this class
        this.name = name;
    }

}

public OtherChild()
{
    public ChildClass cc { get; set; } 

    public OtherChild() 
    {        
       cc = new ChildClass(); // initialize object in the default constructor
    }

    public OtherChild(ChildClass childClass) 
    {        
       cc = childClass; // set to the reference of the passed in childClass
    }
}

当然,这些都使用 .NET 的auto-properties。对于简单的实现,它们可以正常工作。但是,如果您需要(或只是想)拆分成员,这里有一个使用完整属性语法的示例。

public MainClass()
{
    // private backing field is only accessible within this class
    private ChildClass _cc = new ChildClass();

    // public property is accessible from other classes
    public ChildClass cc 
    { 
        get 
        {
            return _cc;
        }
        set
        {
            _cc = value;
        }
    }
}

如果您注意到,这会_cc在成员声明的开头初始化私有。这确保了该cc属性在使用前不需要显式初始化。同样,这更像是一个例子,而不是一个严格的标准。了解 .NET 使用属性和私有成员的所有方式非常重要,因此您可以选择并使用适合您特定情况的最佳方式。


另外,作为旁注,您会注意到我在每个私有成员、属性和构造函数中都包含了一个privatepublic前面。虽然在技术上没有必要,但为每个类成员明确指定可访问性级别通常是一种很好的做法(这促进了封装)。关于封装的维基百科文章有一个相当不错的介绍性解释和示例。

对于未来,我还建议查看一组 .NET 命名约定,例如属性名称、支持字段、方法名称等:

虽然您可能会很好地阅读自己的代码,但遵循这些不同的命名约定可确保其他人也能够更好地阅读和理解它。

于 2013-10-20T18:31:20.037 回答
1

为 OtherChild 创建一个构造函数,该构造函数采用 ChildClass 的实例,或者只需要 name 属性(如果您需要的话)。

public class OtherChild
{
    ChildClass _cc;

    public OtherChild(ChildClass cc)
    {
        this._cc = cc;
    }
}
于 2013-10-20T17:53:32.023 回答
1

最简单的答案很可能是您应该简单地将名称传递给两个子类,而不是将其传递给一个类,然后让这些兄弟姐妹相互交谈。设置名称时ChildClass,只需OtherClass同时设置名称即可。

于 2013-10-20T18:02:04.987 回答
0

如果我正确理解你的问题,这可以工作。请注意,我的语法可能是错误的,因为我对 c# 不是很流利,但我希望你能明白基本的想法

MainClass()
{
     ChildClass _cc = new ChildClass();
     OtherChild _oc = new OtherChild();
     ChildClass cc = get {return _cc;} set{_cc = value;}
     OtherChild oc = get {return _oc;} set{_oc = value;}
     oc.Parent = this;
     //Set the name property of childclass
     string childName = "some name";
}

ChildClass()
{
    public string name {get; set;}
}

OtherChild()
{
     //Here i want to get the name property from ChildClass()
     //Doing this will make a new instance of ChildClass,  which will not have the name property set.
     Public MainClass parent {get; set;}
     ChildClass cc = parent.cc; 

}
于 2013-10-20T17:53:15.547 回答
0

只是想我会添加你可能真的想在一个类的实例或不同的类类型之间共享......所以如果实际意图是......

A)..ALL.. ChildClass 的实例共享完全相同的名称,您可以使用“静态”您可以使用属性访问器隐藏成员是静态的事实

B)不同类型的类的不同实例需要共享信息。然后在实例化类时进行交叉引用(在此示例中,ChildClass 和 OtherChild 是不同的类类型)在此示例中,您实际上希望能够随时更改一个实例中的信息,并且仍然与其他实例...

C)此代码的“更好/更清洁”版本(更复杂但更标准): ....如果必须始终作为引用(对共享值),请考虑将成员变量更改为属性...考虑制作部分'构造函数'与其他示例一样,如果信息共享必须双向..如果有很多共享信息在两个方向上,请考虑必须指向另一个..考虑将单独的 SharedInfoClass 传递给两者构造函数,如果不同类的所有实例共享完全相同的信息,则引用静态类可以避免将 SharedInfoClass 传递给构造函数的需要被认为比“静态类”更干净(但更复杂)是单例设计模式

********** 解决方案 A ******************

// ... information shared across all instances of a class
// Class A  a1,a2;    a1,a2  share exact same values for certain members
class MainClass
{
     void Method()
    {
         ChildClass cc = new ChildClass();
         OtherChild oc = new OtherChild();

         //Set the name property of childclass
         ChildClass.s_name = "some name"; // obviously a shared static because using ChildClass.members not cc.member
         cc.Name = "some name";  // now all instances of ChildClass will have this name

    }
}


class ChildClass
{
    // *** NOTE  'static' keyword ***
    public static string s_name;   // externally refered to by ChildClass.s_name

    // this property hides that s_name is a static which is good or bad depending on your feelings about hiding the nature of data
    public string Name           
    {
        get
        {
            return s_name;
        }
        set // singleton so never set only created first use of get
        {
            s_name = value;
        }
    }
}

class OtherChild
{
    public OtherChild()
    {
    }

    void Method()
    {
        ChildClass cc = new ChildClass();
        string str = cc.Name;
        // cc will have the same name as the cc in MainClass
    }
}

********* 解决方案 B ***************

class BMainClass
{
    void Method()
    {
        BChildClass cc = new BChildClass();
        BOtherChild oc = new BOtherChild( );
        oc.m_SharedChildClassInfo = cc;

        //Set the name property of childclass
        cc.name = "some name";  // only this instance of BChildClass will have this name, but it visible in BOtherChild
    }
}

class BChildClass
{
    public string name {get; set;}
}

class BOtherChild
{
    public BChildClass m_SharedChildClassInfo;

    void Method()
    {
        BChildClass cc = m_SharedChildClassInfo; 
        // cc will have the same name as the cc in MainClass
        // in fact it is the exact same instance as declared in MainClass so evetythng is the same
    }
}

********** 解决方案 C ******************

// this one example shows both 
//  a set of data shared across all instances of two class
//  and a set of data sharted between 2 specific classes
class CMainClass
{
    void Method()
    {
        CSharedBetweenSome sharedSomeInstances = new CSharedBetweenSome();
        CChildClass cc = new CChildClass(sharedSomeInstances);
        COtherChild oc = new COtherChild(sharedSomeInstances);

        //Set the name property of childclass
        cc.sharedAllValue = "same name for everyone";  // ALL  instance of ChildClass will have this name, ALL instances BOtherChild will be able to acess it
        sharedSomeInstances.name = "sane name for cc and oc instances";

    }
}

// Interface - sometimes to make things clean / standard between different classes defining an interface is useful
interface ICShareInfoAll
{
    string sharedAllValue { get; set; }
}

class CSharedInto : ICShareInfoAll
{
    // Singletone pattern - still an instance, rather than a static, but only ever one of them, only created first time needed
    private static CSharedInto s_instance;
    public static CSharedInto Instance
    {
        get
        {
            if( s_instance == null )
            {
                s_instance = new CSharedInto();
            }
            return s_instance;
        }
        private set // singleton  never set only created first use of get
        {
            //s_instance = value;
        }
    }
    // variables shared with every instance of every type of child class
    public string sharedAllValue { get; set; }
}

// One child class using  jointly shared and shared with all
class CChildClass :  ICShareInfoAll
{
    private CSharedBetweenSome sharedSomeInstance;

    public CChildClass(CSharedBetweenSome sharedSomeInstance)
    {
        this.sharedSomeInstance = sharedSomeInstance;
    }

    // Shared with all 
    public string sharedAllValue {
        get { return CSharedInto.Instance.sharedAllValue;  }           
        set { CSharedInto.Instance.sharedAllValue = value; }
        }

    // Shared with one other
    public string sharedAnotherInstanceValue {
        get { return sharedSomeInstance.name;  }           
        set { sharedSomeInstance.name = value; }
        }

}

class COtherChild :  ICShareInfoAll
{
    private CSharedBetweenSome sharedSomeInstance;

    public COtherChild(CSharedBetweenSome sharedSomeInstance)
    {
        this.sharedSomeInstance = sharedSomeInstance;
    }

    public string sharedAllValue {
        get { return CSharedInto.Instance.sharedAllValue;  }           
        set { CSharedInto.Instance.sharedAllValue = value; }
        }

    void Method()
    {
        string val = sharedAllValue;  // shared across instances of 2 different types of class
        string val2 = sharedSomeInstance.name;  // currenlty shared across spefic instances 
    }
}
于 2018-09-05T17:38:13.303 回答