开发者

How to share a variable between two classes?

How would you share the same object between two other objects? For instance, I'd like something in that flavor:

class A
{
   private string foo_; // It could be any other class/st开发者_Go百科ruct too (Vector3, Matrix...)

   public A (string shared)
   {
       this.foo_ = shared;
   }

   public void Bar()
   {
       this.foo_ = "changed";
   }
}

...
// inside main
string str = "test";
A a = new A(str);

Console.WriteLine(str); // "test"
a.Bar();
Console.WriteLine(str); // I get "test" instead of "changed"... :(

Here, I don't want to give a ref to the Bar method. What I want to achieve is something that would look like that in C++:

class A
{
  int* i;
public:
  A(int* val);
};

A::A (int* val)
{
  this->i = val;
}

I read there is some ref/out stuff, but I couldn't get what I'm asking here. I could only apply some changes in the methods scope where I was using ref/out arguments... I also read we could use pointers, but is there no other way to do it?


This has nothing to do with sharing objects. You passed a reference to a string into the A constructor. That reference was copied into the private member foo_. Later, you called B(), which changed foo_ to "changed".

At no time did you modify str. str is a local variable in main. You never passed a reference to it.

If you had wanted to change str, you could have defined B as

   public void Bar(ref string s)
   {
     this.foo_ = "changed";
     s = this.foo_;
   }

Consider:

public class C
{
    public int Property {get;set;}
}

public class A
{
    private C _c;
    public A(C c){_c = c;}

    public void ChangeC(int n) {_c.Property = n;}
}

public class B
{
    private C _c;
    public B(C c){_c = c;}

    public void ChangeC(int n) {_c.Property = n;}
}

in main:

C myC = new C() {Property = 1;}
A myA = new A(myC);
B myB = new B(myC);

int i1 = myC.Property; // 1
myA.ChangeC(2);
int i2 = myC.Property; // 2
myB.ChangeC(3);
int i3 = myC.Property; // 3


Wrap your string inside a class. You need to do this because strings are immutable. Any attempt to change a string actually results in a new string.

class Foo {
    class StringHolder {
        public string Value { get; set; }
    }
    private StringHolder holder = new StringHolder();
    public string Value  {
       get { return holder.Value; }
       set { holder.Value = value; }
    }
    public Foo() { }
    // this constructor creates a "linked" Foo
    public Foo(Foo other) { this.holder = other.holder; } 
}

// .. later ...

Foo a = new Foo { Value = "moose" };
Foo b = new Foo(a); // link b to a
b.Value = "elk"; 
// now a.Value also == "elk"
a.Value = "deer";
// now b.Value also == "deer"


I would split my answer to 2 parts: 1) If the variable is a reference type than it is already shared since you pass its reference to all interested objects. The only thing you should pay attention is that the reference type instances are mutable. 2) If the variable is a value type than you would have to use ref or out or some wrapper that is mutable and you can change the value inside the wrapper using a method or a property. Hope that helps.


You need to pass the paramter as a reference to your method,

    class A
        {
            private string foo_; // It could be any other class/struct too (Vector3, Matrix...) 

            public A(string shared)
            {
                this.foo_ = shared;
            }

            public void Bar(ref string myString)
            {
               myString = "changed";
            }
        }

static void Main()
        {
            string str = "test";
            A a = new A(str);

            Console.WriteLine(str); // "test" 
            a.Bar(ref str);
            Console.WriteLine(str);

        }


When a variable is a string, it is a reference. Try to clone the string. http://msdn.microsoft.com/en-us/library/system.string.clone.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜