Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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# - Fatal编程技术网

C#返回抽象类中的派生类

C#返回抽象类中的派生类,c#,C#,我想为GPGGA、GPGSV等创建一个NMEA消息解析器。每个消息都派生自抽象类NMEAMsg 因此,我需要为每种消息类型覆盖parseToken: 但是,我不知道如何在抽象类中返回派生类 运行此代码时,用户未处理我收到的无效CastException 我需要publicstaticnmeamsgparse(stringsrc)方法返回派生类,如GGA或GSA //NMEAMsg.cs public abstract class NMEAMsg { public static NMEAM

我想为GPGGA、GPGSV等创建一个NMEA消息解析器。每个消息都派生自抽象类NMEAMsg

因此,我需要为每种消息类型覆盖
parseToken

但是,我不知道如何在抽象类中返回派生类

运行此代码时,用户未处理我收到的
无效CastException

我需要
publicstaticnmeamsgparse(stringsrc)
方法返回派生类,如
GGA
GSA

//NMEAMsg.cs
public abstract class NMEAMsg
{
    public static NMEAMsg parse(string src)
    {
        NMEAMsg nmeaMsg = (NMEAMsg)new object();

        var tokens = src.Split(',');
        tokens[tokens.Length - 1] = tokens[tokens.Length - 1].Split('*')[0];

        nmeaMsg.parseTokens(tokens);

        return nmeaMsg;
    }

    public abstract void parseTokens(string[] tokens);
}


//GGA.cs
public class GGA : NMEAMsg
{
    public double latitude;
    public double longitude;

    public override void parseTokens(string[] tokens)
    {
        Double.TryParse(tokens[1], out this.latitude);
        Double.TryParse(tokens[2], out this.longitude);
    }
}

//GSA.cs
public class GSA : NMEAMsg
{
    public double hdop;

    public override void parseTokens(string[] tokens)
    {
        Double.TryParse(tokens[1], out this.hdop);
    }
}

//main.cs
string src = "$GPGGA,123,323*23";

var data = NMEAMsg.parse(src);

if (data is GGA) {
   //Do stuff here  
} else if (data is GSA) {
   //Do stuff here
}

您可能需要以下内容:

public static NMEAMsg parse(string src)
{
    var tokens = src.Split(',');
    tokens[tokens.Length - 1] = tokens[tokens.Length - 1].Split('*')[0];

    NMEAMsg nmeaMsg = null;
    if (tokens[0] == "$GPGGA")
    {
        nmeaMsg = new GGA();
    }
    else if (tokens[0] == "$GPGSA")
    {
        nmeaMsg = new GSA();
    }
    else
    {
        throw new Exception("Unrecognized type: " + tokens[0]);
    }

    nmeaMsg.parseTokens(tokens);

    return nmeaMsg;
}

其中,根据解析字符串的开头实例化正确的类,然后调用特定类“
parseTokens()
方法实现以完成解析。

NMEAMsg-NMEAMsg=(NMEAMsg)new object()在我看来有点奇怪。。。为什么要创建一个新对象并将类强制转换为它?为什么不创建您的类:
NMEAMsg-NMEAMsg=new-NMEAMsg()?关于Roman的评论,你能解释一下什么是
NMEAMsg NMEAMsg=(NMEAMsg)新对象()吗确实是这样做的,还是您希望它能做什么?这是给你错误的那一行吗?那一行对我来说毫无意义
to
NMEAMsg NMEAMsg=new GGA()
@Roman我不能创建那个类
new NMEAMsg()
,因为它是一个抽象类class@Tim然后添加逻辑以决定实例化哪个类<代码>NMEAMsg NMEAMsg;if(something){nmeaMsg=new GGA();}if(somethingelse){nmeaMsg=new GSV();}
很好的解决方案,只有几个问题:i)没有办法动态创建派生对象?ii)我的API设计好还是有其他更好的实现?@Tim你所说的
动态
是什么意思?您可以通过反射来实现这一点,但对于您的用例来说,这可能有点过头了(除非您将拥有10多个类)。唯一的其他改进是将创建提取到方法中,因此您可以执行类似于
NMEAMsg-NMEAMsg=GetParser(tokens[0])的操作
@Rob cuz我将从
NMEAMsg
衍生出大约6个类,如果我使用
if else
的方式,这将是一个很大的问题,只要尝试其他更好的方式,我将检查
反射
样式。谢谢!:)@罗布几乎解释了这一点。事情可以动态编码,但它永远不会因为我们想要它而神奇地工作。即使进行反射,也可能需要在某个地方定义一些映射/配置,将字符串中的值映射到类名,以便动态创建使用反射的实例。我希望你能找到你想要的。