C # Область видимости переменных и объектов при параметризации в методы - PullRequest
6 голосов
/ 08 марта 2009

Я широко использую наследование, полиморфизм и инкапсуляцию, но я только что понял, что не знаю следующего поведения области видимости объекта и переменной. Разница лучше всего показана с кодом:

public class Obj
{
    public string sss {get; set;}

    public Obj()
    {
        sss = "0";
    } 
}     

public partial class testScope : System.Web.UI.Page
 {
    protected void Page_Load(object sender, EventArgs e)
    { 
        Obj a = new Obj(); 
        String sss = "0";            
        Context.Response.Write(sss); // 0

        FlipString(sss);
        FlipString(a.sss);
        Context.Response.Write(sss + a.sss); // 0 0

        FlipObject(a);
        Context.Response.Write(a.sss); // 1
        Context.Response.End();
    }

    public void FlipString(string str)
    { str = "1"; }

    public void FlipObject(Obj str)
    { str.sss = "1"; }
}

Поэтому я подумал, что когда переменная передается в метод, изменения ограничиваются областью применения метода. Но кажется, что если объект передается в метод, который изменяет свои свойства, выходит за пределы метода.

Я мог бы принять это, если бы правилом было то, что такое поведение существует для объекта, а не для переменных, но в .net все является объектом, строкой (как в примере с System.String) я предсказываю область действия параметра, который передаю в метод?

Ответы [ 3 ]

18 голосов
/ 08 марта 2009

Вы никогда не передаете объект в качестве аргумента - вы всегда передаете ссылку или значение типа значения. Если вы не используете ключевое слово ref, аргументы передаются по значению, т. Е. Начальное значение параметра является оцененным значением аргумента, и изменения в значении параметра не отображаются вызывающей стороной.

Однако, очень важно понимать, что значение параметра (для ссылочного типа) равно просто ссылка . Если вы измените содержимое объекта, на который ссылается ссылка, то , который change будет виден вызывающей стороной.

Эта тема заслуживает более чем нескольких параграфов - я предлагаю вам прочитать мою статью о передаче параметров в .NET для получения дополнительной информации.

1 голос
/ 08 марта 2009

Класс (в вашем случае Obj) - это ссылочный тип , поэтому, когда вы вызываете функцию, вы действительно передаете ссылку (вы можете думать об этом, как о безопасном типе). указатель) на этот объект. Если вы хотите предотвратить изменения в изменчивых объектах (т.е. классах / ссылочных типах), то вам необходимо клонировать этот объект, прежде чем передавать его в подходящую функцию (или просто подумайте о том, чтобы сделать его структурой, чтобы она копировалась по значению). *

1 голос
/ 08 марта 2009

Я думаю, что я только что понял, что гуглится, некоторые вещи в .net являются типами «значений», а другие - «ссылочными» типами, поэтому для типов значений значение дублируется при маршалинге в метод, но ссылочные типы иметь указатель like или ссылку, переданную в метод, который явно имеет ту же область видимости, что и родительский. Итак, тогда мой вопрос: как определить, является ли что-то типом значения или нет, я вижу, что все структуры, подобные int, являются типами значений, но строки выглядят как структуры, даже если они являются объектами System.String?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...