2009-07-06 4 views
2

나는이 같은 클래스가 : 지금 ...이 이도의 경우C# 인덱서 재산권 질문

var someClass = new SomeClass(); 
var p = someClass.Privileges[13]; 

public class SomeClass 
{ 
    private const string sessionKey = "__Privileges"; 
    public Dictionary<int, Privilege> Privileges 
    { 
     get 
     { 
      if (Session[sessionKey] == null) 
      { 
       Session[sessionKey] = new Dictionary<int, Privilege>(); 
      } 

      return (Dictionary<int, Privilege>)Session[sessionKey]; 
     } 
    } 
} 

을 ... 더 키 (13)가 없다, 나는를 얻을 것이다 이 같은 오류 :

The given key was not present in the dictionary.

나는 위와 같은 방법으로 액세스 할 수있는 특성을 가지고 싶습니다

, BU 키가없는 경우 기본 객체를 반환합니다.

나는이 같은 인덱서 속성을 만드는 시도

...

public Privilege Privileges[int key] 
    { 
     get 
     { 
      try { return _privileges[key]; } 
      catch { return new Privilege(); } 
     } 
    } 

...하지만 그것은 C#을 2008 언어 기능이 아니다 것 같습니다.

같은 방법으로 속성에 액세스 할 수 있지만 키가없는 경우 기본 개체를 가져 오는 방법은 무엇입니까?

답변

5

원하는 동작이있는 인덱서를 사용하여 고유 한 IDictionary 기반 클래스를 정의한 다음 스톡 사전 클래스가 아닌 해당 인스턴스를 속성 가져 오기 도구에 반환해야합니다.

2

Indexers (C# 포함)은 this 키워드와 함께 사용해야합니다.

난 당신이 뭔가를하려는 생각 :

SomeClass foo; 
var bar = foo[100]; 

또는이 인덱서를 정의 : 당신은 같은 privelege 항목에 액세스 할 수 있도록 직접 SomeClass에서 정의 할 수 있습니다

public Privilege this[int key] 
{ 
    get 
    { 
     try { return _privileges[key]; } 
     catch { return default(Privelege); } 
    } 
} 

IDictionary<TKey, TValue>에서 구현되는 사용자 정의 클래스 (실제로 데이터를 저장하기 위해 내부적으로 Dictionary<TKey, TValue 포함). 당신은 다음처럼 사용할 수 있습니다

가 좀 더 노력이 필요하지만, 당신이 제안하는 것 구문은, 대부분의 appropiate 할 수있는
SomeClass foo; 
var bar = foo.Priveleges[100]; 

.

+0

을 생각. 이것은 프로그램을 디버그하기 어렵게 만듭니다. 왜냐하면 종종 첫 번째 예외 추적을 사용하여 디버깅하기를 원하기 때문에 많은 예외가 있기 때문에 더 느리게 처리됩니다. 따라서 프로그램의 속도가 느려지고 예외가 예상되는 설계상의 사실에 반하여 작동합니다. 예외적이다. 키가 존재하는지 여부를 먼저 확인하고 시도하지 않고 예외를 잡는 것이 훨씬 좋습니다. –

+0

@ Eric : 매우 공정한 점 - 내가 답장을 게시하기 전에 나는 그것을 알고 있었다. 그러나 문제는 질문의 속성/인덱서 ​​측면에 더 관련되어있었습니다. 원래 질문에 대한 의견을 게시해야합니다. – Noldorin

-1

당신은 값 검색이 구문을 사용한다 :

public Privilege this[int key] 
{ 
    get 
    { 
     var value = (Privilege)null; 
     if(!_privileges.TryGetValue(key, out value)) 
      value = new Privilege(); 
     return value; 
    } 
} 

나는 IDictionary의 사용에 많은 이런 종류의 필요성이를, 그래서 나는 몇 가지 확장 방법을 만들어 : 이제

public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> d, TKey key) 
{ 
    TValue v = default(TValue); 
    d.TryGetValue(key, out v); 
    return v; 
} 
public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> d, TKey key, Func<TValue> value) 
{ 
    TValue v = d.Get(key); 
    if (v == null) 
    { 
     v = value(); 
     d.Add(key, v); 
    } 
    return v; 
} 

을 다음과 같이 쓸 수 있습니다 :

public Privilege this[int key] 
{ 
    get 
    { 
     return _privileges.Get(key,() => new Privilege()); 
    } 
} 
+1

유효하지 않은 C#! 인덱서는'this' 키워드와 함께 만 사용할 수 있습니다. – Noldorin

6

C#은 명명 된 인덱서를 지원하지 않습니다.

인덱서 속성 대신 일반적인 방법을 사용 해본 적이 있습니까? 모든 프로그래밍 문제가 해결하기 위해서는 멋진 구문을 사용해야합니다. 그렇습니다. 집계 된 사전을 사용하여 자신의 IDictionary 구현을 만들고 속성 액세스 동작을 변경할 수 있습니다. 그러나 값을 가져 오거나 기본값을 반환하는 무언가에 실제로 필요한 것은 무엇입니까?

나는 당신의 클래스에 다음과 같은 방법을 추가 할 수

: 더 나은 아직

protected Privilege GetPrivilege(int key) 
{ 
    try { return _privileges[key]; } 
    catch { return new Privilege(); } 
} 

또는 흐름 제어 메커니즘으로 예외 처리를 피하기 : 제어 흐름이 나쁘다으로 예외 처리를 사용

protected Privilege GetPrivilge(int key) 
{ 
    Privilege priv; 
    if(_privileges.TryGetValue(key, out priv)) 
     return priv; 
    else 
     return new Privilege(); 
} 
+0

좋은 조언. 내 문제를 해결하기 위해 당신의 충고를했습니다. 이전에는 흐름 제어에 예외 처리를 사용했지만 지금까지는 나쁜 것으로 생각하지 않았습니다. 감사. –