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