简体   繁体   中英

How to pass in the “modifier” string returned by the function?

class test
{
  public String get() {return s;}
  private String s="World";
}

class modifier
{
   public static void modify(ref String v)
   {
     v+="_test";
   }
}

String s1="Earth";


modifier.modify(ref s1); <-------- OK

test c=new test();
modifier.modify(ref c.get()); <------- Error

How to pass in the "modifier" string returned by the function? Assignment through another String object is unacceptable. So how will the copy is created.

You're trying to write C++ code in C#. You'll need to approach this the C# way. Add a property for test.s, instead of a method called "get()". We'll call this new property "MyString" in the code below:

class test
{
    public String MyString
    {
        get
        {
            return s;
        }

        set
        {
            s = value;
        }
    }

    private String s = "World"; 
}

class modifier
{
    public static string modify(String v)
    {
        return v + "_test";
    }
}

test c = new test();
c.MyString = modifier.modify(c.MyString);

If you dont like Matthew Watson's answer and you want to stay to your approach, the way to go is by using StringBuilder.That is a String that can change its value without creating a new one!

What i mean:
Normal String's value cant be changed, what is happening is that a new String is being created....and the pointer(that points to the String you want to change its value) points from now on to this new String. All other pointers....that "were pointing" to the old String .....are still pointing...to the old String!(the String's value didnt change!)
I am not sure if thats clear enough but you have to understand this if you want to play with Strings.This is exactly why s1 cant change its value.

The workaround is with StringBuilder:

    class test
{
    public StringBuilder get() { return  s; }
    private StringBuilder s = new StringBuilder("World");
}

class modifier
{
    public static void modify(StringBuilder v)
    {
        v.Append("_test");
    }
}

And some test code : (of course all this comes with processing cost...but i dont think that will be an issue for now)

        StringBuilder s1 = new StringBuilder("Earth");

        System.Diagnostics.Debug.WriteLine("earth is {0}", s1);
        modifier.modify(s1); //<-------- OK
        System.Diagnostics.Debug.WriteLine("earth is {0}",s1);

        test c=new test();
        StringBuilder aa=c.get();
        System.Diagnostics.Debug.WriteLine("earth is {0}", aa);
        modifier.modify(aa); //<------- Error(not anymore)
        System.Diagnostics.Debug.WriteLine("earth is {0}", c.get());

Before you use the code try to understand how String and StringBuilder works

You have to create a temporary variable:

string tmp = c.get();
modifier.modify(ref tmp);

Because you are passing your parameter by reference.

The class test is designed such that its field s can't be reassigned (changed to point to a new object) from outside the class. That's because s is private , and the get() method only returns s , hence can't reassign it.

Either change the class test to allow the outside world to reassign s somehow, or use reflection to access a private field from the outside.

You can use a property with a get/set-eccessor and then pass to the modify() a test object:

class test
{
    public String myString 
    { 
         get { return s; } 
         set { s = value; } 
    }

    private String s="World";
}

class modifier
{
    public static void modify(test myTest)
    {
        myTest.myString += "_test";
    } 
}

test c = new test();
modifier.modify(c);

Console.WriteLine(c.myString); //World_test

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM