简体   繁体   English

在C#中基于变量创建变量类型

[英]Create variable type based on variable in C#

I am parsing DataField 's out of a larger Message . 我正在从更大的Message解析DataField The Message is in the format RecordHeader|DataFieldKey|DataField|DataFieldKey|DataField|DataFieldKey|DataField|DataFieldKey|DataField (There are no delimiters, just there for effect.) The DataFieldKey block defines the length and type of the DataField that follows. Message是在格式RecordHeader | DataFieldKey |数据字段| DataFieldKey |数据字段| DataFieldKey |数据字段| DataFieldKey |数据字段 (有没有分隔符,只是在那里效果。)的DataFieldKey块定义的长度和类型DataField后面。 I have a DataField class which is used to inherit base functionality for various DataField derived types 我有一个DataField类,用于继承各种DataField派生类型的基本功能

After I parse my DataFieldKey I know the type I need to create and the chunk of the byte[] to copy out of the message into the DataField. 在解析了我的DataFieldKey后,我知道我需要创建的类型以及要将消息复制到DataField中的byte []的块。

switch(fieldId)
{
    case (0):
        GPSData dataField = new GPSData(dataFieldContent);
        break;
    case (1):
        DebugEvent dataField = new DebugEvent(dataFieldContent);
        break;
    case (2):
        DigitalData dataField = new DigitalData(dataFieldContent);
        break;
    case (3):
        Driver dataField = new Driver(dataFieldContent);
        break;
    //case etc
    default:
        Debug.WriteLine("Message {0}. Location {1} Unable to process unknown data field type ({2})", recordHeader.SequenceNumber, dfk.FieldPosition, fieldId);
        break;
}

This leads to errors like the following Cannot implicitly convert type 'Namespace.TripType' to 'Namespace.GPSData' 这导致如下错误无法将类型'Namespace.TripType'隐式转换为'Namespace.GPSData'

I can see that the name is defined in the first case and all the following fail. 我可以看到名称是在第一种情况下定义的,所有以下内容都失败了。 I'm not sure what to do here. 我不知道该怎么做。 I want to be able to create the correct type for the DataField, move on to call a method or two within it, and then rinse repeat for the next field. 我希望能够为DataField创建正确的类型,继续调用其中的一个或两个方法,然后为下一个字段冲洗重复。 Is there some inheritance trick I could be using? 我可以使用一些继承技巧吗? Do I need to name each var dataField0 to dataFieldX? 我是否需要将每个var dataField0命名为dataFieldX?

switch(fieldType) is lazy hardcode for checking DataField.FieldId switch(fieldType)是用于检查DataField.FieldId惰性硬编码

Have tried the following, but it just has more errors. 尝试了以下内容,但它只是有更多错误。 I have renamed DataField to DataFieldBase as I also have two Interfaces IDataFieldBase and IDataFieldImpl to make sure I implement things everywhere. 我已经改名为DataFieldDataFieldBase因为我也有两个接口IDataFieldBaseIDataFieldImpl ,以确保我实现的事情随处可见。

DataFieldBase dataField = null;

switch(fieldId)
{
    case (0):
        dataField = new GPSData();
        dataField.Content = dataFieldContent;
        (dataField as GPSData).TestArray = dataFieldContent;
        break;
//etc
  • Cannot use local variable 'dataField' before it is declared 在声明之前不能使用局部变量'dataField'
    • Occured everywhere dataField ws used (3 times) 到处都是dataField所使用的(3次)
    • I thought DataFieldBase dataField = null; 我以为DataFieldBase dataField = null; declared it 宣布它
  • 'Ctrack.DMT.Message.GPSData' does not contain a constructor that takes 0 arguments 'Ctrack.DMT.Message.GPSData'不包含带0参数的构造函数
    • I don't actually have a no argument constructor 我实际上没有一个没有参数的构造函数
    • After I made one this error went away 在我做了一个之后,这个错误就消失了

To the best of my knowledge this won't work in the way that you have set it up, because even though the objects in second, third, etc conditions of the switch statement only get created at runtime, the compiler still sees them as the type that the first condition creates them as at compile time. 据我所知,这将不会以您设置的方式工作,因为即使switch语句的第二,第三等条件中的对象仅在运行时创建,编译器仍将它们视为键入第一个条件在编译时创建它们。

If all the dataField types inherit from a common ancestor, use that as your dataField type for every switch condition, or even declare it as the ancestor type with value null before the switch and then just assign the various values during the switch conditions. 如果所有dataField类型都从公共祖先继承,则将其用作每个切换条件的dataField类型,或者甚至在切换之前将其声明为值为null的祖先类型,然后在切换条件期间分配各种值。

If they don't inherit from a common ancestor, then see if you can't design in that way with common data and functionality in the ancestor class, or even use an interface. 如果它们不从一个共同的祖先继承,那么看看你是否不能以这种方式设计祖先类中的通用数据和功能,甚至使用接口。

Edit: 编辑:

Or declare the dataField as type object with a null value before the switch? 或者在切换之前将dataField声明为具有空值的类型对象?

Code to try: 代码尝试:

class CommonData
{
    public string CommonStuff { get; set; }
}

class GPSData : CommonData
{
    public string GPSStuff { get; set; }
}

class DigitalData : CommonData
{
    public string DigitalStuff { get; set; }
}

class DriverData : CommonData
{
    public string DriverStuff { get; set; }
}

public static class FieldStuff
{
    public static void TryStuff(int aFieldId)
    {
        CommonData dataField = null;

        switch (aFieldId)
        {
            case (0):
                dataField = new GPSData();
                dataField.CommonStuff = "abcd";
                (dataField as GPSData).GPSStuff = "bcde";
                break;
            case (1):
                dataField = new DigitalData();
                dataField.CommonStuff = "abcd";
                (dataField as DigitalData).DigitalStuff = "cdef";
                break;
            case (2):
                dataField = new DriverData();
                dataField.CommonStuff = "abcd";
                (dataField as DriverData).DriverStuff = "defg";
                break;
            default:
                break;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM