2013-04-06 51 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