2010-10-21 13 views
7

moje przeczucie mówi, że nie powinienem wykonywać następujących czynności. Nie dostaję żadnych ostrzeżeń na ten temat.Czy mogę zmodyfikować przekazany parametr metody?

void test(DateTime d) 
{ 
d = d.AddDays(2); 
//do some thing with d 
} 

czy jest to bardziej właściwe

void test(DateTime d) 
{ 
DateTime _d = d.AddDays(1); 
//do some thing with _d 
} 

Z jakiegoś powodu zawsze obsługiwane przekazywane parametry jak w drugim przykładzie. Ale nie jestem pewien, czy to naprawdę nieistotne ... może to po prostu nieuczciwy kod.

Nie sądzę, że metoda wywołująca będzie używać zmodyfikowanej wartości. ktoś ma jakieś opinie

Odpowiedz

14

Zmiany wartości parametru są niewidoczne dla rozmówcy, chyba że jest to parametr ref lub out.

To nie przypadku jeśli wprowadzić zmiany do obiektu typu odniesienia określoną przez parametr. Na przykład:

public void Foo(StringBuilder b) 
{ 
    // Changes the value of the parameter (b) - not seen by caller 
    b = new StringBuilder(); 
} 

public void Bar(StringBuilder b) 
{ 
    // Changes the contents of the StringBuilder referred to by b's value - 
    // this will be seen by the caller 
    b.Append("Hello"); 
} 

Wreszcie, jeśli parametr jest przekazywany przez odwołanie, zmiana jest widziany:

public void Baz(ref StringBuilder b) 
{ 
    // This change *will* be seen 
    b = new StringBuilder(); 
} 

Więcej na ten temat, zobacz moje article on parameter passing.

+0

Dzięki za artykuł ... Przeczytam to dziś wieczorem na mój lot – Brad

4

Możesz to zmienić, ale zmiana nie wróci do rozmówcy.

Jeśli jest to ValueType -> THE kopia obiektu jest wysyłany

Jeśli jest to RefernceType ->Kopiowanie odniesienia obiekt zostanie wysłany przez wartość. W ten sposób właściwości obiektu mogą zostać zmienione, ale nie samo odniesienie - wywołujący i tak nie zauważy zmiany.

Jeśli zostanie wysłany ref -> Odnośnik można zmienić.

W C++ można użyć const, aby zapobiec zmianie, ale C# tego nie ma. Ma to jedynie na celu zapobieżenie przypadkowemu zmianie przez programistę - w zależności od tego, gdzie użyto const.

+0

To zależy od szczegółów. W tym bardzo konkretnym przykładzie, ponieważ DateTime jest strukturą i ma semantykę wartości, to prawda. Inne argumenty, z semantyką odniesienia, odzwierciedlałyby tę zmianę z powrotem do osoby dzwoniącej. –

+0

@Harper: Nie, jeśli OP zmienia wartość parametru, zamiast dokonywać zmian w obiekcie *, o którym mowa * przez wartość parametru. Zobacz moją odpowiedź na przykład różnicy między tymi dwoma. –

+0

@Harper, 'foo = ...' nie będzie odzwierciedlać na stronie wywołania dla struct lub class *, chyba że * jest to konkretnie parametr 'ref' (lub' out'). To, co robisz * członkom typu referencyjnego * będzie odzwierciedlać, co zrobisz * z samym referencją * nie będzie. –

0

Jeśli chcesz mieć dostęp do oryginalnej wartości, użyj drugiej metody.

Jeśli nie dbasz o oryginalną wartość, możesz użyć jednego z nich (prawdopodobnie używałbym jeszcze drugiego).

Tak czy inaczej, nie skrzywdzisz wartości innych osób (nawet jeśli ponownie przypiszesz wartość, to nie nastąpi powrót do dzwoniącego) w tym przypadku.

Powiązane problemy