2012-06-21 22 views
6

"MyClass" (C#) nesnesinin bir nesneyi bir parametreye nasıl geçirebilirim? örnek:Değeriyle C cinsinden geçirin #

MyClass obj = new MyClass(); 
MyClass.DontModify(obj); //Only use it! 
Console.Writeline(obj.SomeIntProperty); 

...

public static void DontModify(MyClass a) 
{ 
    a.SomeIntProperty+= 100;// Do something more meaningful here 
    return; 
} 
+4

İnsanlar 'struct' kullanmanızı söyleyebilir: İşte ICloneable nasıl kullanılacağına ilişkin bir aldatma örneğidir. Yapma. – SLaks

+0

indir: (CloneExtensions) nuget'ten. Bu, sığ bir kopya istediğinizi belirtmek için kullanabileceğiniz bayrakları kabul eden GetClone() yöntemiyle C# nesnesini genişletir. https://www.nuget.org/packages/CloneExtensions/1.2.0 – alsafoo

cevap

9

Varsayılan olarak, nesne türleri C# cinsinden değere geçirilir. Ancak bir yönteme nesne başvurusu ilettiğinizde, nesnede değişiklikler kalıcıdır. Nesnenin değişmez olmasını istiyorsanız, klonuna klonlamanız gerekir.

Bunu yapmak için sınıfınızda ICloneable arabirimini uygulayın.

public class MyClass : ICloneable 
{ 
    private int myValue; 

    public MyClass(int val) 
    { 
    myValue = val; 
    } 

    public void object Clone() 
    { 
    return new MyClass(myValue); 
    } 
} 
+2

Ne yazık ki ICONable, derin veya sığ bir kopyası olup olmadığını tanımlamıyor. Sonunda, satırları aşağısında referanslar kopyalamaya devam edebilirsiniz (kendinizi yazmadığınız sınıfları kullanırken). Ve Generics'in önceliği olarak, ICONeable bir nesneyi döndürür, bu yüzden sen de bir döküm yapmalısın ... her şey oldukça çirkin. – linac

+2

'Clone' yönteminde' return MemberwiseClone(); 'yazabilirsiniz. –

+0

Kullanıcının klonlamaya ihtiyacı olduğu sınıfın örnek kodu okuyarak sellf-yazılı bir sınıf olduğunu varsayalım. Bu durumda yeni bir nesne oluşturarak klonu kontrol edebilirsiniz. Tabii ki gerekirse gömülü türleri klonlamanız gerekir. –

4

Varsayılan olarak, değeri tarafından geçirilir. Ancak, nesne başvurusunu değerini kullanarak geçirirsiniz; bu, nesnenin içindeki değerleri yine de düzenleyebileceğiniz anlamına gelir.

Nesnenin hiç değişmemesini önlemek için, nesneyi yönteme aktarmadan önce gerçekten klonlamanız gerekir. Bu, orijinal nesnenizin bir kopyası olan yeni bir örnek oluşturma yöntemini uygulamanızı ve ardından kopyayı geçirmenizi gerektirir.

2
public static void DontModify(MyClass a) 
{ 
    MyClass clone = (MyClass)a.Clone(); 
    clone.SomeIntProperty+= 100;// Do something more meaningful here 
    return; 
} 
1

Dönüş değeri, yönteminize iletmek için nesnenizde bir Klonlama yöntemi oluşturabilirsiniz. C# referans türlerini değere göre iletemez, bu yüzden bu iyi bir alternatif olabilir.

1
class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p1 = new Person() 
     { 
      Name = "Alsafoo", 
      Address = new Address() 
      { 
       City = "Chicago" 
      } 
     }; 

     Person p2 = new Person(p1.Address); 
     p2 = p1.GetClone(CloningFlags.Shallow); 
     p2.Name = "Ahmed"; 
     p2.Address = new Address(){City = "Las Vegas"}; 
     Console.WriteLine("p1 first name: {1} --- p1 city: {2} {0}p2 first name: {3} ---- p2 city: {4}", 
      Environment.NewLine, p1.Name, p1.Address.City, p2.Name, p2.Address.City); 
     Console.ReadKey(); 
    } 
} 
public class Person 
{ 
    public Person() 
    {} 
    public Person(Address a) 
    { 
     Address = a; 
    } 
    public string Name { get; set; } 
    public Address Address { get; set; }   
} 

public class Address 
{ 
    public string City { get; set; } 
} 

İndir bu uzantı https://www.nuget.org/packages/CloneExtensions/1.2.0

İlgili konular