2012-01-11 41 views
10

Tôi đang làm việc trên một đối tượng trong C# nơi tôi cần mỗi cá thể của đối tượng để có một id duy nhất. Giải pháp của tôi cho điều này chỉ đơn giản là để đặt một biến thành viên tôi gọi idCount trong lớp và trong constructor tôi sẽ có:Tăng số ID duy nhất trong hàm tạo

objectID = idCount; 
idCount++; 

Tôi nghĩ rằng điều này sẽ giải quyết vấn đề của tôi, nhưng có vẻ như idCount không bao giờ được tăng lên mặc dù hàm tạo được gọi nhiều lần. Ví dụ, nếu idCount = 1, objectID cho tất cả các đối tượng vẫn còn 1. Tại sao không idCount ++ làm việc?

Mọi trợ giúp sẽ được đánh giá cao. Xin lỗi nếu lời giải thích của tôi không đầy đủ, tôi không chắc cách giải thích nó nữa.

+1

Bạn muốn có một biến tĩnh cho idCount. –

+1

Nếu bạn không cần số nguyên tăng dần, GUID mới có thể tạo một ID duy nhất. Bạn cũng cần phải tính đến quyền truy cập luồng - nếu có - khi sử dụng phương pháp "tĩnh". –

Trả lời

1

Bạn có thể sử dụng biến tĩnh trong lớp của mình được cập nhật khi đối tượng được khởi tạo.

public class Foo 
{ 
    private static int ID = 0; 
    private int myId = 0; 

    public int MyId 
    { 
     get { return myId; } 
    } 

    public Foo() 
    { 
     ID++; 
     this.myId = ID; 
    } 
} 
+0

+1 - khóa là giá trị gia tăng là tĩnh nhưng id cá thể vẫn là duy nhất. Tuy nhiên, đây không phải là chủ đề an toàn - hãy xem đề xuất trong @sablinkenlights câu trả lời về khóa liên động nếu bạn muốn nó là chủ đề an toàn. – bryanmac

26

Bạn cần một thuộc tính tĩnh trong lớp, NHƯNG, bạn cần gán nó cho biến mẫu trong lớp nếu bạn muốn mỗi đối tượng chứa id được tạo.

Ngoài ra, bạn sẽ muốn sử dụng Interlocked.Increment trên quầy trong trường hợp bạn đang cập nhật nhiều trường cùng một lúc:

public class Foo 
    { 
     private static int m_Counter = 0; 

     public int Id { get; set; } 

     public Foo() 
     { 
      this.Id = System.Threading.Interlocked.Increment(ref m_Counter); 
     } 
    } 
+0

+1 - chính xác như tôi đã chỉ ra trong câu trả lời của @ Browman98. – bryanmac

+0

Tôi nghĩ đơn giản hơn nếu chúng ta sử dụng 'volatile' thay vì' Interlocked.Increment'? –

+2

@DannyChen: Nó có thể đơn giản hơn nhưng không an toàn hơn. Xem thảo luận này để biết thêm chi tiết: http://stackoverflow.com/questions/154551/volatile-vs-interlocked-vs-lock –

0

Như tất cả mọi người đã chỉ ra, các biến tĩnh là những câu trả lời cụ thể cho câu hỏi của bạn. Nhưng các biến tĩnh chỉ có phạm vi trong quá trình mà chúng được tạo ra và không có mối quan hệ giữa các quá trình (ví dụ, một môi trường web cân bằng tải).

Nếu những gì bạn đang tìm kiếm là một cách duy nhất để xác định một trường hợp đối tượng trong suốt thời gian tuổi thọ của nó, tôi đề nghị một cái gì đó như:

byte[] bytes = new byte[8]; 

RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();    
crypto .GetBytes(bytes); 

long id = BitConverter.ToInt64(bytes, 0); 

này sẽ cung cấp cho bạn một số ngẫu nhiên trong đó có một cực kỳ thấp (khoảng 0-1 trong 100.000.000) cơ hội va chạm và bạn không cần phải lo lắng về việc theo dõi nó.

1

Bạn đặt IdCount là thành viên tĩnh của MyObject.

public class MyObject 
    { 
     static int idCount = 0; 

     private int _objectID; 
     public int ObjectID 
     { 
      get { return _objectID; } 
     } 


     public MyObject() 
     { 
      idCount++; 
      _objectID = idCount; 
     } 
    } 
0
public sealed class SingletonIdGenerator 
{ 
    private static long _id; 
    private SingletonIdGenerator() 
    { 
    } 

    public string Id 
    { 
     get { return _id++.ToString().Substring(8); } 
    } 

    public static SingletonIdGenerator Instance { get { return Nested.instance; } } 

    private class Nested 
    { 
     static Nested() 
     { 
      _id = DateTime.Now.Ticks; 
     } 
     internal static readonly SingletonIdGenerator instance = new SingletonIdGenerator(); 
    } 
} 
Các vấn đề liên quan