2011-02-03 4 views
1

내 또 다른 하나는 나무에 대한 질문을 볼 수 없습니다.단일 데이터 입력에서 교차 참조 구조

배경

나는 (지금)에 걸쳐 문화의 작은 범위를 등가물을 요리에 미리 정의 된 구조를 조회 할 수있는 요구 사항을 가지고있다. 구조는 변하지 않을 것이나 다른 문화 및/또는 등가물이 도입 될 가능성은 매우 강력합니다.

문제

나는 장소 제가 주어진 한 내용의 핵심을 유지할 수 있도록 해주는 2 '구조'에 넣어 좋아하지만 동시에 허용 할

나 지능적으로 입력 동일한 측정은 한 번만 가능합니다. 아래 예에서는 UK 측정 값을 파트너 Metric 및 미국 카운터 값으로 반환하기 위해 동등한 항목 만 만들었습니다. 내 목표는 미국의 대응 등, 등의 질문

이 같은 암시을 너무 많이 요구하고 주어진다면이 하나의 입력에서, 구조가 영국 상당을 다시 침을 할 수있을 것이다 것 구조가이 방식으로 작동 할 수 있어야합니다. 그런 일에 대해 물어 보는 것은 나쁜 습관입니까 ?? 그런 딜레마를 해결하는 방법은 무엇입니까?

예 콘솔 응용 프로그램

채찍까지 : 속히,

// this should produce a value of **CupLitre** 
var eqv = conversion["CupUS"][LocaleM.Metric]; 

어쨌든 : 최종 게임은 동등한이의 라인을 따라 하나의 라이너로 제작되어야한다는 것 아래에 코드를 붙여 넣으십시오 (.net v3.5).

using System; 
using System.Collections.Generic; 
using UnitOfMeasurements; 

namespace UnitOfMeasurements 
{ 
    [Flags] 
    public enum LocaleM 
    { 
     None = 0, //(0000) 
     Metric = 1, //(0001) 
     UK = 2,  //(0010) 
     US = 4,  //(0100)  
    } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     // single structure representing UK equivalents 
     // this should be extensible to any equivalent 
     var conversionUK 
      = new Dictionary<string, Dictionary<LocaleM, string>> 
       { 
        {"PintUK", 
         new Dictionary<LocaleM, string> 
            { 
             {LocaleM.US, "PintUS"}, 
             {LocaleM.Metric, "Litre"} 
            } 
        }, 
        {"FlOzUK", 
         new Dictionary<LocaleM, string> 
            { 
             {LocaleM.US, "FlOzUS"}, 
             {LocaleM.Metric, "MilliLitre"} 
            } 
        }, 
        {"CupUK", 
         new Dictionary<LocaleM, string> 
            { 
             {LocaleM.US, "CupUS"}, 
             {LocaleM.Metric, "CupLitre"} 
            } 
        } 
       }; 

     // basic printout of results 
     Console.WriteLine(string.Format("{0}\t{1}\t{2}", "Key","US","Metric")); 
     foreach (var item in conversionUK) 
     { 
      Console.WriteLine(string.Format("{0}\t{1}\t{2}", 
       item.Key, 
       item.Value[LocaleM.US], 
       item.Value[LocaleM.Metric])); 
     } 
     Console.WriteLine(string 
      .Format("Here's an example of our direct 'query' - {0}", 
      conversionUK["CupUK"][LocaleM.Metric])); 
     Console.Read(); 
    } 
} 

간단하면서도 우아한 대답에 행운을 보입니다.

[편집] - 나 문자열 될 입력 ("PintUK", "CupMetric") 등을위한 요구 사항이 구체적 변환을 생성 하류 (IVolumeUnit)Activator.CreateInstance(eqv) 방법 구동된다 이들 값과 같은 필수임을 추가해야 지정된 캐릭터 라인 명의 클래스 접근 방식에 따라

+0

있습니까? 그렇지 않은 경우, F #은 언어의 일부로 구운이 기능을 가지고 있습니다. http://blogs.msdn.com/b/andrewkennedy/archive/2008/08/29/units-of-measure-in-f-part-one- introduction-units.aspx – Juliet

+0

Juliet - alas, only C# –

답변

1

는 모든 매핑이 양방향 있다고 가정하고 A-> B와 B-> C 다음> A-

c를 나는 각 default name (상호 문화)처럼 무언가의 개념을 도입 할 경우 변환 할 항목. 코드에서 예를 들어 이러한 기본 이름은 '파인트를'수 'FlOz'과 '컵'

UPDATE : 코드를 더 간단을 위해 닷넷 튜플로 대체 지정 MapKey 클래스입니다.

class MapClass 
{ 
    private readonly Dictionary<string, string> _localToDefaultNameMap = new Dictionary<string, string>(); 

    private readonly Dictionary<Tuple<string, LocaleM>, string> _defaultNameToLocalMap = new Dictionary<Tuple<string, LocaleM>, string>(); 

    public void AddMapping(string defaultName, LocaleM locale, string localName) 
    { 
     _localToDefaultNameMap.Add(localName, defaultName); 
     _defaultNameToLocalMap.Add(Tuple.Create(defaultName, locale), localName); 
    } 

    // maps from source name to target 
    public string Map(string sourceLocalName, LocaleM targetLocale) 
    { 
     string defaultName = _localToDefaultNameMap[sourceLocalName]; 
     var mapKey = Tuple.Create(defaultName, targetLocale); 
     var localName = _defaultNameToLocalMap[mapKey]; 
     return localName; 
    } 
} 

사용법 : ReSharper에서에 의해 생성 된

// Creating map: 
var map = new MapClass(); 
map.AddMapping("Pint", LocaleM.UK, "PintUK"); 
map.AddMapping("Pint", LocaleM.US, "PintUS"); 
map.AddMapping("Pint", LocaleM.Metric, "Litre"); 

string ukPintMappedToUS = map.Map("PintUK", LocaleM.US); 

업데이트 2 MapKey 평등 회원 : 당신은 C#을 제한

class MapKey 
{ 
    ... 

    public bool Equals(MapKey other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return Equals(other.Locale, Locale) && Equals(other.Key, Key); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != typeof (MapKey)) return false; 
     return Equals((MapKey) obj); 
    } 

    public override int GetHashCode() 
    { 
     int result = 0; 
     result = (result * 397)^Locale.GetHashCode(); 
     result = (result * 397)^(Key != null ? Key.GetHashCode() : 0); 
     return result; 
    } 

} 
+0

Snowbear - 사과, 나는 그것을 컴파일 할 수 있도록 예제 편집의 자유를 취했습니다. 이것은 거의 '거기'이지만 예제 사용법에 따라 예외가 발생합니다. 나는 그것을 볼 것입니다 ...하지만 일반적으로, 나는이 접근법을 정말 좋아합니다. –

+0

@jim, 고마워, 나는 Studio를 열어 너무 게으르다. 그래서 나는 그 틈을 남겨 두었다. 연장 해줘서 고마워. – Snowbear

+0

스노 베어 (Snowbear)가 최종 변경되었습니다. 이것은 지금 완벽하게 작동합니다. 덕분에 +1 –