Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.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# 从对象到适当类型:这是/a“吗;对",;如何使用这个非泛化的对象返回API?_C#_Json_Generics - Fatal编程技术网

C# 从对象到适当类型:这是/a“吗;对",;如何使用这个非泛化的对象返回API?

C# 从对象到适当类型:这是/a“吗;对",;如何使用这个非泛化的对象返回API?,c#,json,generics,C#,Json,Generics,我写的一些代码中有一个特别的方面给我带来了一些小麻烦,我无法找出原因——所有的类型检查和转换都让我感到不安。代码按现在的方式工作。我想知道是否有更好的方法来处理代码中特定于类型的方面 我使用的是一个非泛化的返回JSON解析器,对象,它让我在泛化代码中阅读各种咒语 解析方法的签名是publicstaticobjectjsondecode(stringjson)它返回的对象的运行时类型可以是ArrayList、Hashtable、double或string。我在Twitter搜索响应上调用JsonD

我写的一些代码中有一个特别的方面给我带来了一些小麻烦,我无法找出原因——所有的类型检查和转换都让我感到不安。代码按现在的方式工作。我想知道是否有更好的方法来处理代码中特定于类型的方面

我使用的是一个非泛化的返回JSON解析器,
对象
,它让我在泛化代码中阅读各种咒语

解析方法的签名是
publicstaticobjectjsondecode(stringjson)
它返回的对象的运行时类型可以是
ArrayList
Hashtable
double
string
。我在Twitter搜索响应上调用
JsonDecode
方法,它将结果tweets作为表单的顶级对象返回:

{"results":[
 {"text":"@twitterapi  http:\/\/tinyurl.com\/ctrefg",
 "to_user_id":396524,
 "to_user":"TwitterAPI",
 "from_user":"jkoum",
 "metadata":
 {
  "result_type":"popular",
  "recent_retweets": 109

 }, ... MORE-DATA ...}
我使用
JsonDecode(stringjson)
方法的上下文是

private IList<Tweet> searchResult = new List<Tweet>();
var jsonDecoded = JSON.JsonDecode(responseString);

IList rawTweets = 
    (IList)((Hashtable)jsonDecoded)["results"];

foreach (var rawTweet in rawTweets) 
{
    searchResult.Add(new Tweet((Hashtable) rawTweet));
}
我是否正确地处理了
json
方法中的类型检查?构建
IList
并构建搜索结果
IList
的代码片段中的强制转换如何?你会用不同的方式写代码吗

作为旁注,完整的代码可以通过以下代码获得:该代码用于演示我将在演讲中介绍的选定.NET功能。
Tweet
类是一个
DynamicObject
,它覆盖了
TryGetMember
,请参见github上的完整列表

谢谢;)


附言:[供参考]这是我上一篇文章的一个更具体的版本,要求对代码进行一次全面的审查

首先,您应该进行一些参数验证。在开始使用“表”之前,请检查它是否为空。否则,您将得到一个未经处理的NullReferenceException,它将混淆您的消费者

接下来,这真的有效吗?“is”关键字(我认为)只适用于引用类型,double是一种值类型。我假设这不起作用,您需要改为执行double.TryParse()

最后,有很多演员都在进行中。当您与第三方API交互时,我认为您应该有一个接口,在该接口中,您可以将“他们奇怪的东西”转换为“您干净的东西”。因此,即使API凌乱且困难,也要清理它并以适当的方式将其呈现给您的消费者。不要宣扬这个糟糕的设计。换句话说,作为一个消费型开发人员,我希望使用一些明显的、干净的数据结构。比如:foreach(Twitter.GetTweets()中的Tweet Tweet)或者其他什么。我不在乎你现在使用json。这一实现对我来说应该是无形的


希望这有帮助……

我不会那样做

首先,您的tweet类不是一个真正的对象,它是一个数据容器。您可以继续使用jsondeconded变量,因为您的tweet类没有添加任何功能或抽象(除了抽象掉JSON解码器)

我会怎么做:

  • 创建保存信息的文件:Tweet和元数据类
  • 创建一个序列化程序,该序列化程序接受JSON字符串并返回Tweet类

  • 通过将其分为两个步骤,并创建真正的类,您将在将来更加轻松。请阅读。

    LukeH是对的,您可能会把
    as混淆起来keyword@rob-谢谢你的回答。关于arg检查,您是对的,它们丢失了,因为这是用于演示目的的示例代码。我不会在生产中忽略它们。至于向用户公开的API:它包括
    IList
    搜索结果,作为名为
    tweets
    的属性公开,以及类
    Tweet
    的动态分派方法,通过覆盖
    DynamicObject
    TryGetMember
    实现。对
    Tweet
    类实例上不存在的属性的访问应该中断,从而显示运行时错误。
     class Tweet : DynamicObject
    {
        private IDictionary<string, string> stringValues = 
            new Dictionary<string, string>();
        private IDictionary<string, double> numberValues =
            new Dictionary<string, double>();
    
        public Tweet(Hashtable rawTweet) 
        {
            FlattenJSON(rawTweet);
        }
    
        //flatten input and assign to correct map/dictionary based on JSON value type
        private void FlattenJSON(Hashtable table)
        {
            foreach (DictionaryEntry entry in table)
            {
                //this code is not handling the case, that the Tweet contains a JSON array
                //not necessary as of now: this code is intended for demo purposes in a talk
                //I'm giving on Friday 2010-06-25
                if (entry.Value is String)
                    stringValues.Add((string)entry.Key, (string)entry.Value);
                else if (entry.Value is Double)
                    numberValues.Add((string)entry.Key, (double)entry.Value);
                else if (entry.Value is Hashtable)
                    FlattenJSON((Hashtable)entry.Value);
            }
        }
        ...
    }