2013-04-06 52 views
0

我有支持不同類型的列表下面的代碼:避免使用泛型投和自定義數據的列表

public enum eType 
{ 
    tInt, 
    tString, 
    tDateTime 
} 

public interface ICustomType<out T> 
{ 
    T Value { get; } 
} 

public abstract class DifferentType 
{ 
    protected DifferentType(eType type, string mnemonic) 
    { 
     Type = type; 
     Mnemonic = mnemonic; 
    } 

    public string Mnemonic { get; private set; } 

    public eType Type { get; private set; } 
} 

public class DateTimeType : DifferentType, ICustomType<DateTime> 
{ 
    public DateTimeType(DateTime value, string mnemonic) 
     : base(eType.tDateTime, mnemonic) 
    { 
     Value = value; 
    } 

    public DateTime Value { get; private set; } 
} 

public class IntType : DifferentType, ICustomType<int> 
{ 
    public IntType(int value, string mnemonic) 
     : base(eType.tInt, mnemonic) 
    { 
     Value = value; 
    } 

    public int Value { get; private set; } 
} 

public class StringType : DifferentType, ICustomType<string> 
{ 
    public StringType(string value, string mnemonic) 
     : base(eType.tString, mnemonic) 
    { 
     Value = value; 
    } 

    public string Value { get; private set; } 
} 

public static class UtilValue 
{ 
    public static T GetValue<T>(DifferentType customType) 
    { 
     return ((ICustomType<T>)customType).Value; 
    } 
} 

public class testTypes2 
{ 
    public testTypes2() 
    { 
     var values = new List<DifferentType> { GetInt(), GetString(), GetDate() }; 

     foreach (var i in values) 
     { 
      switch (i.Type) 
      { 
       case eType.tInt: 
        int resInt = UtilValue.GetValue<int>(i); 
        break; 

       case eType.tString: 
        string resString = UtilValue.GetValue<string>(i); 
        break; 

       case eType.tDateTime: 
        DateTime resDateTime = UtilValue.GetValue<DateTime>(i); 
        break; 
      } 
     } 
    } 

    private DateTimeType GetDate() 
    { 
     return new DateTimeType(new DateTime(2000, 1, 1), "MnemonicDate"); 
    } 

    private IntType GetInt() 
    { 
     return new IntType(5, "MnemonicInt"); 
    } 

    private StringType GetString() 
    { 
     return new StringType("ok", "MnemonicString"); 
    } 
} 

,並希望避免在UtilValue類在行return ((ICustomType<T>)customType).Value;投,任何想法如何在保持設計的同時擺脫這一點?

我甚至不確定這個演員是否昂貴?我的猜測是肯定是

+1

你應該成爲訪問者模式:http://en.wikipedia.org/wiki/Visitor_pattern這應該解決你的問題,並避免演員和開關。 – 2013-04-06 21:08:43

+0

@lasseespeholt:嗨!這看起來像一個有趣的想法,但不知道如何正確實現它。我將不得不閱讀文章幾次,並與這個想法一起玩...感謝您的建議。如果你可以提供這個想法的答案,那將是非常棒的! – ibiza 2013-04-06 21:17:41

+0

現在有一個例子。確切的代碼取決於你想在交換機上做什麼。 – 2013-04-06 21:26:03

回答

1

訪問者模式例如:

interface IDifferentTypeVisitor 
{ 
    void Visit(DateTimeType dt); 
    void Visit(StringType st); 
} 

class DifferentType 
{ 
    public abstract void Accept(IDifferentTypeVisitor visitor); 
} 

class DateTimeType : DifferentType 
{ 
    public void Accept(IDifferentTypeVisitor visitor) 
    { 
     visitor.Visit(this); 
    } 
} 

class StringType : DifferentType 
{ 
    public void Accept(IDifferentTypeVisitor visitor) 
    { 
     visitor.Visit(this); 
    } 
} 

class SomeVisitor : IDifferentTypeVisitor 
{ 
    public void Visit(DateTimeType dt) 
    { 
     //DateTime resDateTime = dt.Value; Or similar 
    } 

    public void Visit(StringType st) 
    { 
     //string resString = st.Value; Or similar 
    } 
} 

public class testTypes2 
{ 
    public testTypes2() 
    { 
     var values = new List<DifferentType> { /* Content */ }; 
     var visitor = new SomeVisitor(); 

     foreach (var i in values) 
     { 
      i.Accept(visitor); 
     } 
    } 
} 

在C#4 dynamic有可能加入這DifferentType節省一些代碼:

public void Accept(IDifferentTypeVisitor visitor) 
{ 
    visitor.Visit((dynamic)this); 
} 

,然後刪除所有其他Accept方法。它傷害了性能,但看起來更好;-)

+0

感謝您提供答案!這很有趣,但是我覺得它有點過於拘束,或者說我不能正確理解這個概念。我只能在訪問者中操作自定義數據類型(例如'DateTimeType'),我如何在測試類(循環中)中公開和使用它? – ibiza 2013-04-06 21:48:02

+0

@ibiza你想在循環中做什麼?請記住,您始終可以爲訪問者添加狀態。 – 2013-04-06 21:50:35

+0

我正在考慮操縱數據(爲了我的目的,我修改了一些答案,每個自定義數據都有一個與其類型相對應的Value屬性,例如'DateTimeType Value {get; private set;}' )直接在循環中。作爲一個例子,我可以在測試類中列出一個'List ',並且想要將所有'DateTimeType'的值添加到該列表中。 – ibiza 2013-04-06 21:57:02