Share variable between multiple classes

前端 未结 5 1527
囚心锁ツ
囚心锁ツ 2021-01-06 13:11

If i have 3 classes, lets say: Mainclass, ChildClass, OtherChild.

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


        
相关标签:
5条回答
  • 2021-01-06 13:51

    Just thought I would add you might actually want to share across instances of a class or different class types.... So if the actual intent is...

    A) ..ALL.. instances of ChildClass share the EXACT SAME name you can use 'static' You can hide the fact the member is static with a Property accessor

    B) DIFFERENT instances of DIFFERENT types of class need to share info. then a cross-reference when the classes are instantiated works (ChildClass and OtherChild being different class types in this example) In this example you actually want to be able to change the info in one instance at any time and still share that new info with the other instance...

    C) 'better/cleaner' versions of this code (more complex but more standard): ....consider changing the member variable to a property if ALWAYS has to be a reference (to the shared value)... consider making part of the 'constructor' as in other examples if the sharing of information has to go both ways.. consider having to point each to the other if there is a lot of shared info going in both directions.. consider a separate SharedInfoClass passed to both constructors if ALL instances of different classes share the EXACT SAME info then referencing a static class can avoid the need to pass the SharedInfoClass to constructor Regarded as cleaner (but more complex) than a 'static class' is the singleton design pattern

    ********** Solution 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
        }
    }
    

    ********* Solution 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
        }
    }
    

    ********** Solution 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 
        }
    }
    
    0 讨论(0)
  • 2021-01-06 13:56

    If I correctly understand your question, this can work. Note, my syntax may be wrong as I'm not super fluent at c# but I hope you can get the basic idea

    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; 
    
    }
    
    0 讨论(0)
  • 2021-01-06 14:02

    The easiest answer is most likely that you should simply pass the name along to both child classes, instead of passing it along to one class and then having those siblings talk to each other. When you set the name of ChildClass, just set the name of OtherClass at the same time.

    0 讨论(0)
  • 2021-01-06 14:03

    Basically, in order to access information from class to class, you must "pass" that information in some way between instances.

    Here is a quick annotated example using your basic setup. I have included a few examples of different ways you could go about sending information between objects:

    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
        }
    }
    

    Of course, those all use .NET's auto-properties. For simple implementations, they work fine. If, however, you needed to (or just wanted to) split a member out, here is an example using the full property syntax.

    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;
            }
        }
    }
    

    If you notice, this initializes the private _cc at the beginning, in the member declaration. This ensures that the cc property does not need to be explicitly initialized before use. Again, this is more an example than a rigid standard. It's important to know all of the ways .NET uses properties and private members, so you may choose and use the best one for your particular situation.


    Also, as a side note, you'll notice that I included either private or public in front of each private member, property, and constructor. While not technically necessary, it is generally good practice to explicitly specify your level of accessibility for each class member (this promotes encapsulation). The Wikipedia article on encapsulation has a pretty decent introductory explanation and examples.

    For the future, I'd also suggest taking a look at a set of .NET naming conventions for things such as property names, backing fields, method names, etc:

    • .net Naming Conventions and Programming Standards - Best Practices (quick reference)
    • The MSDN's Framework Design Guidelines (more extensive)

    While you may be fine reading your own code, following these different naming conventions ensures that others will be more able to read and understand it as well.

    0 讨论(0)
  • 2021-01-06 14:04

    Create a constructor for OtherChild that takes an instance of ChildClass, or just the name property if that is all you need.

    public class OtherChild
    {
        ChildClass _cc;
    
        public OtherChild(ChildClass cc)
        {
            this._cc = cc;
        }
    }
    
    0 讨论(0)
提交回复
热议问题