2010-03-18 6 views
3

일부 데이터를 표현하는 가장 좋은 방법을 찾으려고합니다. 기본적으로 Manufacturer.Product.Attribute = Value 형식을 따릅니다. 뭔가 같은 :..키 값 저장 또는 트리에 더 적합합니까?

한국 전기 * MinimumPrice = 100
Acme.ProductA.MinimumPrice = 50
Acme.ProductB.MinimumPrice = 60
Acme.ProductC.DefaultColor = 블루

그래서 최저 가격 모든 A와 B 제품의 경우를 제외하고는 모든 Acme 제품에서 100을 나타냅니다.이 데이터를 C#에 저장하고 GetValue ("Acme.ProductC.MinimumPrice")가 100을 반환하지만 GetValue ("Acme.ProductA.MinimumPrice ") return 50.

나는 최선의 방법을 모르겠다. 데이터를 나타냅니다. C#에서 코드를 작성하는 명확한 방법이 있습니까?

편집 : 나는 분명하지 않을 수 있습니다. 이것은 텍스트 파일에 저장되어야하고 필자가 준 예제처럼 검색 될 수 있도록 메모리에 저장되어야하는 구성 데이터입니다.

답변

2

텍스트 파일 쓰기를 정확히 다음과 같습니다.

Acme.*.MinimumPrice = 100 
Acme.ProductA.MinimumPrice = 50 
Acme.ProductB.MinimumPrice = 60 
Acme.ProductC.DefaultColor = Blue 

경로/값 쌍 seque로 구문 분석하십시오. nce :

foreach (var pair in File.ReadAllLines(configFileName) 
         .Select(l => l.Split('=')) 
         .Select(a => new { Path = a[0], Value = a[1] })) 
{ 
    // do something with each pair.Path and pair.Value 
} 

이제 원하는 작업에 대한 두 가지 해석이 가능합니다. Acme.*.MinimumPrice 문자열은 Acme.Toadstool.MinimumPrice과 같이 특정 재정의가없는 조회의 경우 파일의 어느 곳에서나 Toadstool을 참조하는 것이 없더라도 100을 반환한다는 것을 의미 할 수 있습니다. 또는 파일에 Toadstool의 다른 특정 언급이있는 경우에만 100을 리턴해야 함을 의미 할 수도 있습니다.

전자의 경우 전체 사전을 평면 사전에 저장할 수 있으며 조회시 일치하는 항목을 찾을 때까지 다른 유형의 키를 계속 시도 할 수 있습니다.

후자의 경우 실제로 존재하지 않는 값을 반환하지 않으려면 경로 구조에서 실제로 발생하는 모든 이름의 데이터 구조를 작성해야합니다. 이것은 나에게 더 믿을만한 것 같습니다.

후자의 옵션을 사용하면 Acme.*.MinimumPrice은 실제로 "이 MinimumPrice 값을 자체적으로 정의 된 값이없는 제품에 추가"라고 말합니다.

Acme.ProductA.MinimumPrice = 50 
Acme.ProductB.MinimumPrice = 60 
Acme.ProductC.DefaultColor = Blue 
Acme.ProductC.MinimumPrice = 100 

이의 좋은 점은 당신은 단지 필요가있다이다 : 이것은 당신이 기본적으로 설정 파일의 완성 된 버전에 해당하는로를 확대, 모든 별표를 제거하는 구문 분석시에는 쌍을 처리 할 수 ​​있음을 의미 플랫 표현 사전을 최종 표현으로 사용하면 내용을보기 위해 TryGetValue 또는 []을 사용할 수 있습니다. 그 결과는 훨씬 더 클 수 있지만 설정 파일의 크기에 따라 다릅니다.

당신 저장 정보 더 최소한의, 그러나 나는으로 시작하고, 정말로 밝혀지면 나중에 다시 구현할 수 있도록 그것을 아주 간단한 API를 제공하기 위해 노력하고 간단한 뭔가 갈 것 필요하다. 룩업 프로세스를 더 복잡하게 만드는 것이 (응용 프로그램에 따라) 전체적으로 더욱 악화 될 수 있음을 알 수 있습니다.

0

나는 당신이 무엇을 요구하고 있는지 확실하지 않지만, 당신이 말하는 것처럼 들린다.

나는 두 가지 경우를 제외하고 모든 제품 ID를 위해, (100)를 고정 된 값을 반환하는 함수가 필요합니다 ProductA 그 경우 ProductB

당신은 심지어 데이터 구조를 필요가 없습니다. 단순 비교 기능은

int GetValue(string key) { 
    if (key == "Acme.ProductA.MinimumPrice") { return 50; } 
    else if (key == "Acme.ProductB.MinimumPrice") { return 60; } 
    else { return 100; } 
} 

을 할 것입니다 또는 당신은

가에 없을 경우 이미 정의 된 경우 값을 반환하거나 (100)하는 기능이 필요

을 요구하고 있었다 나는 Dictionary<string,int>을 사용할 것이다. Dictionary<string, Dictionary<string, Dictionary<string, object>>> : - 예 방식의

class DataBucket { 
    private Dictionary<string,int> _priceMap = new Dictionary<string,int>(); 
    public DataBucket() { 
    _priceMap["Acme.ProductA.MinimumPrice"] = 50; 
    _priceMap["Acme.ProductB.MinimumPrice"] = 60; 
    } 
    public int GetValue(string key) { 
    int price = 0; 
    if (!_priceMap.TryGetValue(key, out price)) { 
     price = 100; 
    } 
    return price; 
    } 
} 
+0

편집을 참조하십시오. 나는이 모든 것을 하드 코딩하지 않을 것입니다. 그래서 두 번째 대답은 100이 사전에도 저장된다는 것을 제외하고는 거의 좋은 결과입니다. –

+0

@JC 왜 원래 질문이 애매한 지 내게 투표 한 이유가 확실하지 않습니다. – JaredPar

0

하나를 들어 당신은 중첩 된 사전을 만들 수 있습니다. 코드에서 "Acme.ProductA.MinimumPrice"를 도트로 분리하고 분할 된 청크에 해당하는 사전 값을 가져 오거나 설정해야합니다.

또 다른 방법은 Linq2Xml을 사용하는 것입니다. Acme를 루트 노드로 사용하고 제품을 루트의 하위 노드로 만들고 특성을 실제로 제품의 특성 또는 하위 노드로 저장할 수 있습니다. 나는 두 번째 솔루션을 선호하지만 수천 가지 제품이 있다면 더 느릴 것입니다.

0

나는 이것에 대해 OOP 방식을 취할 것이다. 당신이 설명하는 방식은 당신의 모든 제품이 좋은 물건으로 표현됩니다. 이것은 다형성의 좋은 사용처럼 보입니다.

내가 모든 제품을 것 같은 ProductA 같은 기본값

virtual MinimumPrice { get { return 100; } } 

그리고 특정 제품, 기능 우선합니다 가상 재산이있는 ProductBase 있습니다

override MinimumPrice { get { return 50; } } 
관련 문제