Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 避免使用泛型和自定义数据列表强制转换_C#_.net_Generics_Interface - Fatal编程技术网

C# 避免使用泛型和自定义数据列表强制转换

C# 避免使用泛型和自定义数据列表强制转换,c#,.net,generics,interface,C#,.net,Generics,Interface,我有以下代码来支持不同类型的列表: public enum eType { tInt, tString, tDateTime } public interface ICustomType<out T> { T Value { get; } } public abstract class DifferentType { protected DifferentType(eType type, string mnemonic) {

我有以下代码来支持不同类型的列表:

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");
    }
}
公共枚举eType
{
色调,
tString,
tDateTime
}
公共接口ICustomType
{
T值{get;}
}
公共抽象类不同类型
{
受保护的差异类型(eType类型,字符串助记符)
{
类型=类型;
助记符=助记符;
}
公共字符串助记符{get;private set;}
公共eType类型{get;private set;}
}
公共类DateTimeType:DifferentitType,ICustomType
{
公共日期时间类型(日期时间值,字符串助记符)
:base(eType.tDateTime,助记符)
{
价值=价值;
}
公共日期时间值{get;private set;}
}
公共类IntType:DifferentitType,ICustomType
{
公共IntType(int值,字符串助记符)
:base(eType.tInt,助记符)
{
价值=价值;
}
公共int值{get;private set;}
}
公共类StringType:DifferentitType,ICustomType
{
公共StringType(字符串值、字符串助记符)
:base(eType.tString,助记符)
{
价值=价值;
}
公共字符串值{get;private set;}
}
公共静态类UtilValue
{
公共静态T GetValue(不同类型customType)
{
返回((ICustomType)customType).Value;
}
}
公共类testTypes2
{
公共测试类型2()
{
var values=新列表{GetInt(),GetString(),GetDate()};
foreach(值中的var i)
{
开关(i型)
{
大小写eType.tInt:
int resInt=UtilValue.GetValue(i);
打破
case eType.t字符串:
字符串resString=UtilValue.GetValue(i);
打破
case eType.tDateTime:
DateTime resDateTime=UtilValue.GetValue(i);
打破
}
}
}
私有日期时间类型GetDate()
{
返回新的DateTimeType(新的DateTime(2000,1,1),“助记符”);
}
私有IntType GetInt()
{
返回新的IntType(5,“助记符”);
}
私有StringType GetString()
{
返回新的StringType(“ok”、“助记符”);
}
}
并希望避免在
return((ICustomType)customType.Value行强制转换
UtilValue
类中,你知道我如何在保留设计的同时摆脱它吗


我甚至不确定这个演员的表演是否昂贵?我的猜测是肯定的。

访客模式示例:

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);
        }
    }
}

然后删除所有其他
Accept
方法。这会影响性能,但看起来更好;-)

你应该进入访客模式:这应该可以解决你的问题,避免演员和开关。@LasseSpeholt:Hi!这看起来是一个有趣的想法,但不确定如何正确实施。我将不得不读几遍这篇文章,并玩弄这个想法……谢谢你的建议。如果你能给出这个想法的答案,那就太棒了!现在有一个例子。确切的代码取决于您想在交换机中执行的操作。感谢您提供答案!这很有趣,但是我发现它有点太拘束了,或者可能是我没有正确理解这个概念。我只能在访问者中操作自定义数据类型(例如,
DateTimeType
),如何在测试类(在循环中)中公开和使用它?@ibiza您想在循环中做什么?请记住,您可以随时向访问者添加状态。我正在考虑直接在循环中操作数据(出于我的目的,我修改了您的答案,每个自定义数据都有一个与其类型相对应的值属性,例如
公共日期时间值{get;private set;}
,用于
日期时间类型
)。例如,我可以在测试类中有一个
列表
,并希望将
日期时间类型
的所有值添加到该列表中。@ibiza然后您只需将该列表存储在
SomeVisitor
中,并在
访问(数据时间类型)
中将日期时间添加到该列表中。在
testTypes2
中,使用方法或属性从访问者检索列表。
public void Accept(IDifferentTypeVisitor visitor)
{
    visitor.Visit((dynamic)this);
}