2008-10-25 50 views
9

Tôi muốn thực hiện tương tự trong C#. Có anyway sử dụng tài sản trong C# với các tham số trong cùng một cách tôi đã thực hiện với tham số 'Key' trong ví dụ VB.NET này?Sử dụng các thuộc tính get set điển hình trong C# ... với tham số

Private Shared m_Dictionary As IDictionary(Of String, Object) = New Dictionary(Of String, Object) 
Public Shared Property DictionaryElement(ByVal Key As String) As Object 
    Get 
     If m_Dictionary.ContainsKey(Key) Then 
      Return m_Dictionary(Key) 
     Else 
      Return [String].Empty 
     End If 
    End Get 
    Set(ByVal value As Object) 
     If m_Dictionary.ContainsKey(Key) Then 
      m_Dictionary(Key) = value 
     Else 
      m_Dictionary.Add(Key, value) 
     End If 

    End Set 
End Property 

Cảm ơn

Trả lời

14

Liệu có cách nào của việc sử dụng tài sản trong C# với các thông số

số Bạn chỉ có thể cung cấp các mặc định tài sản trong C# với một đối số, để lập chỉ mục một ccess (như trong từ điển):

public T this[string key] { 
    get { return m_Dictionary[key]; } 
    set { m_Dictionary[key] = value; } 
} 

Các thuộc tính khác không thể có đối số. Sử dụng hàm thay thế. Bằng cách này, nó được recommented để làm như vậy trong VB vì vậy các ngôn ngữ NET. (C# ...) có thể sử dụng mã của bạn.

Nhân tiện, mã của bạn phức tạp không cần thiết. Bốn điều:

  • Bạn không cần phải thoát khỏi số nhận dạng String. Sử dụng từ khóa trực tiếp.
  • Tại sao không sử dụng ""?
  • Sử dụng TryGetValue, tốc độ nhanh hơn. Bạn truy vấn từ điển hai lần.
  • Trình thiết lập của bạn không phải kiểm tra xem giá trị đã tồn tại chưa.

Public Shared Property DictionaryElement(ByVal Key As String) As Object 
    Get 
     Dim ret As String 
     If m_Dictionary.TryGetValue(Key, ret) Then Return ret 
     Return "" ' Same as String.Empty! ' 
    End Get 
    Set(ByVal value As Object) 
     m_Dictionary(Key) = value 
    End Set 
End Property 
+1

Người trả lời hay. Không biết tại sao bạn đề nghị sử dụng "" thay vì String.Empty mặc dù, ... bản gốc dường như rõ ràng hơn với tôi. – Stimul8d

+4

@ Stimul8d: Tôi không theo. Làm thế nào là '" "' không rõ ràng? Sự khác biệt duy nhất mà tôi thấy giữa hai (và rằng, IMHO, một lập trình viên * nên * thấy) là 'String.Empty' dài gấp sáu lần, do đó nó chiếm không gian nhiều gấp sáu lần và mất ~ 6 lần đọc lâu hơn nó làm cho mã tồi tệ hơn gấp sáu lần. Để so sánh, điều đó giống như chúng ta sẽ sử dụng 'Int32.Zero' thay vì' 0'. –

+1

nosed unicorn: Tôi chỉ sử dụng cùng một đối số tuần trước! –

0

mẫu mã của bạn đập vào mắt tôi là một thiết kế rất lạ và một sự lạm dụng về những gì thuộc tính này được dành cho. Tại sao không chỉ là một phương pháp dụ AddOrUpdateKey:

Public Sub AddOrUpdateKey(ByVal Key As String, ByVal Value as Object) 
    If m_Dictionary.ContainsKey(Key) Then 
     m_Dictionary(Key) = Value 
    Else 
     m_Dictionary.Add(Key, Value) 
    End If 
End Sub 

tài sản của bạn cũng trở String.Empty nếu chìa khóa không tồn tại, nhưng tuyên bố trả lại một Object, cũng không phải một String.

+0

Hi Sören, Sử dụng phương pháp không cho phép tôi sử dụng mã theo cách này: Example.DictionaryElement ["OneKey"] = "Hello world"; Console.WriteLine (Example.DictionaryElement ["OneKey"]); Cảm ơn rất nhiều – Javier

4

Cách "thích hợp" để thực hiện trong C# là tạo lớp con đặc biệt để truy cập bộ sưu tập. Nó phải giữ chính bộ sưu tập hoặc có các liên kết nội bộ tới lớp cha.

3

Đây là một mẫu cho bạn (với những thay đổi dọc theo dòng gợi ý Grauenwolf của):

using System; 
using System.Collections.Generic; 

public class Test 
{ 
    public FakeIndexedPropertyInCSharp DictionaryElement { get; set; } 

    public Test() 
    { 
     DictionaryElement = new FakeIndexedPropertyInCSharp(); 
    } 

    public class FakeIndexedPropertyInCSharp 
    { 
     private Dictionary<string, object> m_Dictionary = new Dictionary<string, object>(); 

     public object this[string index] 
     { 
      get 
      { 
       object result; 
       return m_Dictionary.TryGetValue(index, out result) ? result : null; 
      } 
      set 
      { 
       m_Dictionary[index] = value; 
      } 
     } 
    } 


} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Test t = new Test(); 
     t.DictionaryElement["hello"] = "world"; 
     Console.WriteLine(t.DictionaryElement["hello"]); 
    } 
} 
0

Cảm ơn Konrad, Alan, Grauenwolf,

Tóm lại, tôi không thể sử dụng C thuộc tính # chính xác theo cách tương tự như trong VB.NET ...: _ (Dù sao, câu trả lời của bạn rất hữu ích đối với tôi, và tôi có thể lấy ý tưởng này vào mã C# của tôi.

Ngoài câu trả lời cho tính chất câu hỏi, có những điểm tốt khác.Ví dụ,

  • Sử dụng TryGetValue, nó nhanh hơn. Bạn truy vấn từ điển hai lần.
  • Trình thiết lập của bạn không phải kiểm tra xem giá trị đã tồn tại chưa.

Cảm ơn Sören, quá, sử dụng một phương pháp không phù hợp tốt trong mục tiêu ban đầu của tôi, nhưng cảm ơn rất nhiều.

4

Một nhiều mục đích chung, an toàn hơn, và giải pháp tái sử dụng cho vấn đề của bạn có thể thực hiện một "tham số" lớp tài sản chung chung, như thế này:

// Generic, parameterized (indexed) "property" template 
    public class Property<T> 
    { 
     // The internal property value 
     private T PropVal = default(T); 

     // The indexed property get/set accessor 
     // (Property<T>[index] = newvalue; value = Property<T>[index];) 
     public T this[object key] 
     { 
      get { return PropVal; }  // Get the value 
      set { PropVal = value; } // Set the value 
     } 
    } 

Sau đó, bạn có thể thực hiện bất kỳ số lượng khách sạn thuộc của bạn public class để khách hàng có thể thiết lập/lấy các thuộc tính với một chỉ số, mô tả, khóa bảo mật, hoặc bất cứ điều gì, như thế này:

public class ParameterizedProperties 
    { 
     // Parameterized properties 
     private Property<int> m_IntProp = new Property<int>(); 
     private Property<string> m_StringProp = new Property<string>(); 

     // Parameterized int property accessor for client access 
     // (ex: ParameterizedProperties.PublicIntProp[index]) 
     public Property<int> PublicIntProp 
     { 
      get { return m_IntProp; } 
     } 

     // Parameterized string property accessor 
     // (ex: ParameterizedProperties.PublicStringProp[index]) 
     public Property<string> PublicStringProp 
     { 
      get { return m_StringProp; } 
     } 
    } 

Cuối cùng, mã khách hàng sẽ truy cập vào thuộc tính "tham số" public class của bạn như thế này:

 ParameterizedProperties parmProperties = new ParameterizedProperties(); 
     parmProperties.PublicIntProp[1] = 100; 
     parmProperties.PublicStringProp[1] = "whatever"; 
     int ival = parmProperties.PublicIntProp[1]; 
     string strVal = parmProperties.PublicStringProp[1]; 

Chắc chắn, điều này có vẻ kỳ lạ, nhưng nó thực sự là lừa. Bên cạnh đó, từ góc độ client-code, nó không lạ chút nào - nó đơn giản và trực quan và hoạt động giống như các thuộc tính thực. Nó không phá vỡ bất kỳ quy tắc C# nào, cũng như không tương thích với các ngôn ngữ được quản lý .NET khác. Và từ quan điểm của người triển khai lớp, việc tạo một lớp mẫu thuộc tính có thể tái sử dụng, chung chung, "được tham số hóa" làm cho thành phần mã hóa một luồng tương đối, như được hiển thị ở đây.

LƯU Ý: Bạn luôn có thể ghi đè lớp thuộc tính chung để cung cấp xử lý tùy chỉnh, chẳng hạn như tra cứu được lập chỉ mục, quyền truy cập thuộc tính được kiểm soát bảo mật hoặc bất kỳ thứ gì bạn muốn.

Chúc mừng!

Mark Jones

+0

+1 Cảm ơn Mark, điều này có vẻ tốt! tôi sẽ kiểm tra – Javier

Các vấn đề liên quan