簡體   English   中英

使用 ref 關鍵字的替代方法?

[英]Alternatives to using ref keyword?

作為一個新手,我已經閱讀了使用ref關鍵字傳遞參數的危險。 我想當在程序的一部分中修改 ref 變量然后改變其他地方發生的事情時,很可能會弄亂代碼。 對象最終會非常緊密地耦合。 (我知道可能有些地方ref是值得的。)我還不知道,正在詢問的是替代方案。

例如,在一個程序中,我在啟動時創建了一個通用列表,並在程序的方法中對其進行操作。 在一種方法中:

//a user is asked a question  
//if the response is yes, the list is modified one way and the method returns true  
//if the response is no, the list is modified a different way and the method returns false. 

所以該方法返回一個布爾值,我將列表作為ref傳入。 我有幾種類似的方法,每種方法都向用戶提出獨特的問題,然后以某種方式修改列表。

似乎一個典型的替代方法可能是將列表和一個布爾字段捆綁到它自己的類中。 不知何故,這似乎只是為了方便而創建一個對象,只是為了保存兩條數據,與任何現實世界實體沒有聯系。

那么,您將如何(偽)編碼一個返回泛型列表和布爾值的方法?


編輯:這是一些實際的代碼

 private static bool AskExptQuestion(ref List<StatTest> testList)
        {
            Console.Write(Constants.ExptQText); //experimental groups?
            string response = Console.ReadLine();

            //if response==y, it's experimental 
            if (response == "y")
            {
                //so select all experimental
                var q1List =
                from test in testList
                where test.isExperimental == true
                select test;

                //to copy resulting IEnumerable<List> (q1list) to generic List, must copy/cast IEnumerable to a List<t>
                testList = q1List.ToList();
                return true;
            }
            //and if response==n, it's not experimental 
            else
            {
                //so select all non-experimental
                var q1List =
                from test in testList
                where test.isExperimental == false
                select test;

                testList = q1List.ToList();
                return false;
            }

        }

返回一個列表(或幾乎任何其他東西,就此而言)及其特征,例如布爾值,是ref / out特征的“典型子代”。 此模式用於標准 .NET 庫中的多個位置:

  • Dictionary.TryGetValue使用此模式,根據字典中鍵的存在返回truefalse ,並將 a out設置為返回對象
  • Integer.TryParse (和其他數字類型)使用這種模式,解析成功時返回true ,並在out參數中設置值

之間的區別refoutref給你的方法的選項,以防止舊的對象/值或提供一個新的,而out的力量,你要提供方法返回之前一個新的。

僅僅為了將兩個不相關的類型捆綁在一起而創建一個新類是沒有意義的。

此外,重要的是要了解即使在參數未通過refout傳遞的情況下,也可能會發生對方法參數的修改。 當你傳遞一個可變的引用(即class )類型的對象時,在方法內部對對象所做的任何修改在調用者中都是可見的。

通過refout傳遞的唯一區別是您可以用新的對象替換對象本身,而傳遞沒有ref的引用類型僅限於改變傳入的對象本身。

通過閱讀您的示例和評論,聽起來您可能只希望能夠將一些過濾器應用於集合。 為什么不讓您的函數返回過濾器?

private static Predicate<StatTest> AskExptQuestion()
{
    Console.Write(Constants.ExptQText);  // experimental groups?
    bool response = Console.ReadLine() == "y";  // maybe wrap this up in a function to read a yes/no answer
    return t => t.isExperimental == response;
}

但是,您可能仍然需要bool返回值,它可以成為out參數。 目前尚不清楚這是為了什么。

在 c# 中,參數是按值傳遞的。 對象類型(類)由指向內存中實例的指針實現。 在將對象傳遞給方法的情況下,指針被復制到參數,然后他指向同一個實例。

如果我有:

void foo(MyClass param)
{
    param.x = 7;
}

我在其他地方做的:

MyClass obj = new MyClass();
obj.x = 5;
foo(obj);

然后在調用 foo() 之后,obj 的 x 屬性為 7。

如果 foo 是:

void foo(MyClass param)
{
    param = new MyClass();
    param = 7;
}

那么我原來的 obj 仍然會有 x 等於 5。這是因為我跑過了 param 正在查看的實例。

現在是“ref”關鍵字:

void foo(ref MyClass param)
{
    param = new MyClass();
    param = 7;
}

如果我這樣打電話:

MyClass obj = new MyClass();
obj.x = 5;
foo(ref obj);

在這種組合中,我的 obj 將被設置為 MyClass 的新實例,並且 x 等於 7。 ref 意味着方法中的變量與傳遞的變量相同,而不僅僅是指向相同的實例開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM