2009-06-03 14 views
5

Yukarıdaki sınıfa sahibim. Bunu değiştirmek için nasıl bir yöntem oluşturursunuz?Değiştirilen nesneyi iade etmeyi tercih ediyor musunuz, istemiyor musunuz?

public Class ModifyIt(Class c) 
{ 
    c.Prop = "changed"; 
    return c; 
} 

veya Sonra böyle adlandırılan

public void ModifyIt(Class c) 
{ 
    c.Prop = "changed"; 
} 

...

Class c = ModifyIt(c); 
Console.WriteLine(c.Prop); 
// changed 

veya bu

ModifyIt(c) 
Console.WriteLine(c.Prop); 
// changed 

nedir Tercihiniz?

+0

Neden 'Class x' parametresini ModifyIt() 'a geçiriyorsunuz? Yöntemeniz sadece Sınıf örneğini 'bu' olarak almaz mı? Kodu dikkate alarak zincirleme ile ilgili tüm diğer cevaplar gerçekten işe yaramayacaktır. Benim için eğer sınıfınız daha çok bir değer türüyse, bu durumda örneklerinizi değiştirmemelisiniz, bunun yerine işlemin sonucuyla yeni bir tane döndürmeniz gerekir. – van

cevap

2

Bunu değiştirdikten sonra öğeyi gerçekten döndürdüğünüz ilk yolu yapmakla ilgili en güzel şey, yöntem zincirlemesine izin vermesidir. Böyle bir şey yapabiliriz Anlamı:

c.ModifyIt("hello").MessWithIt("World").ReallyScrewWithIt("!!!"); 

Eğer, zincirleme bir gereksinim öngörüyor sonra örneğini dönebilirsiniz özel sınıf ile mantıklı edin. Eğer değilse, o zaman bunu geçersiz kılabilirsiniz. Buna iyi bir örnek, böyle bir şey yapmak için izin verir StringBuilder sınıftır: - tersi yani bir sonuç dönen yöntemler olmamalı mutators ve Kişisel

myStringBuilder.Replace("!", "?").Append("Something").Remove(4,3); 
+0

"Bunu ikinci yolla yapmanın en güzel yanı [...] yöntem zincirlemesine izin vermesidir". Bence ilk yolu kastediyorsun. Yorum için üzgünüm, henüz düzenleme yapamıyorum. – PatrikAkerstrand

+0

Oops, gönderimi düzenledim, teşekkürler! – BFree

6

, ben command-query separation tercih ederim. Ben return this kalabalık için argümanlar anlamak yani "zincirleme" kolaylığı çağırır:

foo.ChangeThis(23).ChangeThat(45).AndAlso(67); 

ama

var x=foo; 
x.ChangeThis(23); x.ChangeThat(45); x.AndAlso(67); 

olarak bu davaları kodlamak için kesinlikle bir arada avantajları çok kötü değil " komut-sorgu ayrımı "(büyük bir çoğunluğunun% 100'ü olmasa da), bu wikipeida URL'sinde tartışıldığı gibi, ...

3

Nesnenin bir örneğini döndürme veya döndürme seçimi Durumda.

yöntemi ile dönen nesne için ortak bir durum böyle StringBuilder sınıf olarak, builder pattern görülür: Böyle method chaining icra edilecek, değilse,

new StringBuilder("Hello").Append(" ").Append("World!").ToString(); 

Fakat genel olarak ben bir şey döndürmemeyi tercih ederdi. Ortak kullanım vakası, iade edilen nesneyi kullanmamaksa (ve sadece bırakarak), bu bir atık gibi görünecektir.

0

İlk olarak, eğer bir özelliği değiştiriyorsanız, ayrı bir değişiklik işlevine sahip olmayacağım; Mülkiyeti doğrudan değiştirirdim. Bu şekilde, modifikasyon işlevinde belki de birkaç farklı değişiklikle, daha karmaşık bir şeyin basit bir örneğini verdiğinizi varsayalım.

'Class' nesnesini döndüren birini kullanırdım. Aynı anda birden fazla çağrıyı yönlendirmenize izin verir. Yine, bunun aslında daha karmaşık bir sistemin basit bir örneği olduğunu varsayıyorum; bunun yerine MakeModification(), MakeAnotherModification() ve MakeAThirdModification() öğelerini aldığınızı varsayalım.yöntem, dolayısıyla yeni bir değer iade edilmesi beklenmemektedir bir Mutator olduğu gibi yerine, Aslında

Class c = new Class(); 
c.MakeModification().MakeAnotherModification().MakeAThirdModification(); 
0

Ben ikinci tarzı tercih: Eğer 'Class' nesneyi döndürmek, aşağıdaki sözdizimsel nicety alabilirsiniz Gerçek değerin değiştirilmesi bekleniyor. Ancak, ModifyIt'ın gerçek c'nin değiştirileceğini belirtmek için bir ref değişkeni kabul ettiğini belirtmeniz gerekebilir. Burada bir referans türü olmasına rağmen, burada referans değerlerini geçen zamana göre geçirme ve referans türlerini ref ile geçirme arasında hala bir fark vardır. Yukarıdaki durumda

public void ModifyIt(Myclass c) { c = new MyClass(); } 

c değişkeni (örneğin, referans bir kopyalama geçirilir ve sırayla size anlamına gelir yeni instanitiated nesne, işaret değiştirilecek değeriyle geçilecek: Aşağıdaki bakınız Bu durumda Sınıfım türünde iki nesne olacak İşte göstermek için bir örnek:. MOdifyIT o prob anlamına gelmelidir yeni bir nesneye referenct instanitaited olsa

Myclass s = new MyClass() { prop = "value" }; ModifyIt(s); Console.WriteLine(s.prob); // this will print "value" 

null başlatılır, aslında değil mi' t anında, s'nin bir kopyasını sundu. se, ref tarafından geçirilmişse.
Bu yardımcı olur umarız!

1

Kişisel olarak ModifyIt gibi bir işlev oluşturmayı ve mümkün olsaydı oluşturduğum sınıfa koymayı tercih ederim. Her iki yöntemde dediğim nedeni çağrı değişkeni değiştirdiğim için referans olarak geçiyorum. Doğal olarak, bunu tüm işlevler için yapamıyorum, ancak işlev çağrısına ref eklerken, bir değişkeni bir değişkeni referans olarak geçirdiğimi, bir değişkeni değere geçirmediğimi açıklığa kavuşturmaya yardımcı olur. Örnek:

public Class ModifyIt(ref Class c) 

Neden? Çünkü geri geldiğimde ve değeri referans olarak geçtiğim kodu okudum ve daha sonra kod için "kötü" bir şey yapmam gerektiğinden unutabilirim.

İlgili konular