2017-04-11 106 views
0

我有一個包含鍵和值的實體。我的鑰匙是枚舉。這個實體的值是字符串(但是它們的數據類型可能與字符串不同)。c#設置另一個鍵值實體的實體屬性

枚舉例如:

public enum CallKey { 
    CallDate = 1, 
    CallTime = 2, 
    FromPhoneNumber = 3, 
    ToPhoneNumber = 4, 
    Duration = 5, 
    FromOperatorCode = 6, 
    ToOperatorCode = 7 
} 

我鍵值實體是:

public class CallKeyValue { 
    public CallKey CallKey { get; set; } 
    public string Value1 { get; set; } 
    public string Value2 { get; set; } 
} 

我的例子鍵,值數據爲:

CallKey |Value1  |Value2 
1  |11.04.2017 | 
2  |15:43  | 
3  |5311234567 | 
4  |5311234587 | 
5  |13*min  | 
6  |TR   |001 
7  |TR   |002 

現在,我要創造我最後實體從我的關鍵價值實體。

我最後的實體:

public class CallDetail{ 
    public DateTime CallDate { get; set; } //=15.04.2017 15:43 
    public string FromPhoneNumber { get; set; } //=5311234567 
    public string ToPhoneNumber { get; set; } //=5311234587 
    public int Duration { get; set; } //=13 
    public DurationUnit DurationUnit { get; set; } //=1 (this is enum 1:min, 2:hour etc...) 
    public string FromOperatorCountry { get; set; } //=TR 
    public string FromOperatorId { get; set; } //=001 
    public string ToOperatorCountry { get; set; } //=TR 
    public string ToOperatorId { get; set; } //=002 
} 

哪種方式來設置Call​​Detail實體?反思,財產或其他更好的方式?

+0

如果你可以在這裏提供一些背景,這可能是有益的。你想在這裏解決什麼問題? – jcb

+0

我有一個性能問題。這只是一個例子,但我有更多的數據。反思是一個很好的解決方案,但我認爲(可能是我的方式錯了,我不確定),這很慢。 –

+0

反思本身可能不起作用(除非你正在做的事情比你的問題更明顯)。例如,您需要了解'CallDetail'來確定「CallKey.Duration」類型的字符串「13 * min」將需要拆分爲'CallDetail.Duration'和'CallDetail.DurationUnit'。前者可以通過搜索相同名稱的屬性來找到,但後者以任何方式都不明顯(再次,除非有更多元信息可用,通用反映解決方案可以訪問)。 – jcb

回答

0

好吧,我想我找到了一些關於這個問題的解決方案。我做了3個測試,我在這裏添加一個簡單的示例。我認爲第二對我來說是最好的,但我決定做一個加載測試。

public class CallTest { 
public void TestCode() { 
    var items = new List<CallKeyValue> 
    { 
     new CallKeyValue {CallKey = CallKey.CallDate, Value1 = "11.04.2017"}, 
     new CallKeyValue {CallKey = CallKey.CallTime, Value1 = "15:43"}, 
     new CallKeyValue {CallKey = CallKey.FromPhoneNumber, Value1 = "5311234567"}, 
     new CallKeyValue {CallKey = CallKey.ToPhoneNumber, Value1 = "5311234587 "}, 
     new CallKeyValue {CallKey = CallKey.Duration, Value1 = "13*min"}, 
     new CallKeyValue {CallKey = CallKey.FromOperatorCode, Value1 = "TR",Value2 = "001"}, 
     new CallKeyValue {CallKey = CallKey.ToOperatorCode, Value1 = "TR",Value2 = "002"}, 
    }; 
    var st = new Stopwatch(); 

    //Test 1: ElapsedMilliseconds: 50, ElapsedTicks: 122023 
    st.Start(); 
    IDictionary<string,dynamic> expando = new ExpandoObject(); 
    foreach(var item in items) { 
     expando.Add(item.CallKey.ToString(),null); 
     expando[item.CallKey.ToString()] = new { Value1 = item.Value1,Value2 = item.Value2 }; 
    } 

    var cd = new CallDetail { 
     CallDate = DateTime.Parse(expando[CallKey.CallDate.ToString()].Value1 + " " + expando[CallKey.CallTime.ToString()].Value1), 
     FromPhoneNumber = expando[CallKey.FromPhoneNumber.ToString()].Value1, 
     ToPhoneNumber = expando[CallKey.ToPhoneNumber.ToString()].Value1, 
     Duration = Convert.ToInt32(expando[CallKey.Duration.ToString()].Value1.ToString().Split('*')[0]), 
     DurationUnit = GetEnumKeyOfUnit(expando[CallKey.Duration.ToString()].Value1.ToString().Split('*')[1]), 
     FromOperatorCountry = expando[CallKey.FromOperatorCode.ToString()].Value1, 
     FromOperatorId = expando[CallKey.FromOperatorCode.ToString()].Value2, 
     ToOperatorCountry = expando[CallKey.ToOperatorCode.ToString()].Value1, 
     ToOperatorId = expando[CallKey.ToOperatorCode.ToString()].Value2 
    }; 
    st.Stop(); 
    Console.WriteLine(st.ElapsedMilliseconds); 
    Console.WriteLine(st.ElapsedTicks); 
    st.Reset(); 

    //Test 2: ElapsedMilliseconds: 0, ElapsedTicks: 328 
    st.Start(); 
    var cd3 = items.Select(s => { 
     IDictionary<string,dynamic> expando2 = new ExpandoObject(); 
     expando2.Add(s.CallKey.ToString(),null); 
     expando2[s.CallKey.ToString()] = new { Value1 = s.Value1,Value2 = s.Value2 }; 

     var item = new CallDetail { 
      CallDate = DateTime.Parse(expando2[CallKey.CallDate.ToString()].Value1 + " " + expando2[CallKey.CallTime.ToString()].Value1), 
      FromPhoneNumber = expando2[CallKey.FromPhoneNumber.ToString()].Value1, 
      ToPhoneNumber = expando2[CallKey.ToPhoneNumber.ToString()].Value1, 
      Duration = Convert.ToInt32(expando2[CallKey.Duration.ToString()].Value1.ToString().Split('*')[0]), 
      DurationUnit = GetEnumKeyOfUnit(expando2[CallKey.Duration.ToString()].Value1.ToString().Split('*')[1]), 
      FromOperatorCountry = expando2[CallKey.FromOperatorCode.ToString()].Value1, 
      FromOperatorId = expando2[CallKey.FromOperatorCode.ToString()].Value2, 
      ToOperatorCountry = expando2[CallKey.ToOperatorCode.ToString()].Value1, 
      ToOperatorId = expando2[CallKey.ToOperatorCode.ToString()].Value2 
     }; 
     return item; 
    }); 


    st.Stop(); 
    Console.WriteLine(st.ElapsedMilliseconds); 
    Console.WriteLine(st.ElapsedTicks); 
    st.Reset(); 

    //Test 3: ElapsedMilliseconds: 0, ElapsedTicks: 1390 
    st.Start(); 
    var cd2 = new CallDetail { 
     CallDate = DateTime.Parse(items.FirstOrDefault(f => f.CallKey == CallKey.CallDate)?.Value1 + " " + items.FirstOrDefault(f => f.CallKey == CallKey.CallTime)?.Value1), 
     FromPhoneNumber = items.FirstOrDefault(f => f.CallKey == CallKey.FromPhoneNumber)?.Value1, 
     ToPhoneNumber = items.FirstOrDefault(f => f.CallKey == CallKey.ToPhoneNumber)?.Value1, 
     Duration = Convert.ToInt32(items.FirstOrDefault(f => f.CallKey == CallKey.Duration)?.Value1.Split('*')[0]), 
     DurationUnit = GetEnumKeyOfUnit(items.FirstOrDefault(f => f.CallKey == CallKey.Duration)?.Value1.Split('*')[1]), 
     FromOperatorCountry = items.FirstOrDefault(f => f.CallKey == CallKey.FromOperatorCode)?.Value1, 
     FromOperatorId = items.FirstOrDefault(f => f.CallKey == CallKey.FromOperatorCode)?.Value2, 
     ToOperatorCountry = items.FirstOrDefault(f => f.CallKey == CallKey.ToOperatorCode)?.Value1, 
     ToOperatorId = items.FirstOrDefault(f => f.CallKey == CallKey.ToOperatorCode)?.Value2 
    }; 

    st.Stop(); 
    Console.WriteLine(st.ElapsedMilliseconds); 
    Console.WriteLine(st.ElapsedTicks); 

} 

private DurationUnit? GetEnumKeyOfUnit(string unit) { 
    switch(unit) { 
     case "min": 
      return DurationUnit.Minute; 
     case "hour": 
      return DurationUnit.Hour; 
    } 
    return null; 
} 
} 

在此測試之前,我嘗試使用反射。反射性能比3次測試差。這是elapsedmilliseconds約爲100,也elatedticks非常高。我可以使用第二個測試,直到找到更好的方式。

相關問題