繁体   English   中英

C#JSON反序列化:Type是接口或抽象类,无法实例化

[英]C# JSON Deserialization : Type is an interface or abstract class and cannot be instantiated

我正在使用这个C#项目,该项目使用API与在线交易平台Poloniex进行通信

此代码应该在钱包中获得余额:

var x = await polo_client.Wallet.GetBalancesAsync();

虽然此代码提供此错误:

获取钱包时出错:无法创建Jojatekok.PoloniexAPI.WalletTools.IBalance类型的实例。
Type是接口或抽象类,无法实例化。
路径'1CR.available',第1行,第20位。

在Helper.cs这里:

[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
internal static T DeserializeObject<T>(this JsonSerializer serializer, string value)
{ 
    using (var stringReader = new StringReader(value))
    {
        using (var jsonTextReader = new JsonTextReader(stringReader))
        {
            return (T)serializer.Deserialize(jsonTextReader, typeof(T));
        }
    } 
}

调用它的代码是:

public T GetData<T>(string command, params object[] parameters)
{
    var relativeUrl = CreateRelativeUrl(command, parameters);
    var jsonString = QueryString(relativeUrl);
    var output = JsonSerializer.DeserializeObject<T>(jsonString);
    return output;
}

有人能告诉我为什么我在反序列化这个JSON响应时出错了吗?

响应是JSON,以下是它的示例:

{
"1CR":{"available":"0.00000000","onOrders":"0.00000000","btcValue":"0.00000000"},
"ABY":{"available":"0.00000000","onOrders":"0.00000000","btcValue":"0.00000000"}
}

是不是JSON,错误是自我描述的。 您无法实例化接口或抽象类。 它们只是他们所代表的功能或对象结构的蓝图。

例如,你不能这样做:

var something = new ISomething();

但是,你可以这样做:

ISomething something = new Something();

您只需要该接口的一些具体实现。 就像是:

public JsonReceived : IBalance
{
// rest of the implementation
}

或者可能已由第三方提供,请检查其SDK文档。

这就是我为使其工作所做的工作。 感谢来自Guru.com的Chris让这个工作。 伟大的家伙,非常好的价格。 你可以在这里找到他: http//www.guru.com/freelancers/deatc

private IDictionary<string, IBalance> GetBalances()
{
    var postData = new Dictionary<string, object>();
    var data = PostData<IDictionary<string, Balance>>("returnCompleteBalances", postData);
    var returnData = new Dictionary<string, IBalance>();

    foreach (string key in data.Keys)
    {
        returnData.Add(key, data[key]);
    }

    return returnData;
}

由于对象的DeSerialization导致的错误,内部创建一个Jobject并将其作为输入Generic投射,在上面的场景中,因为我们无法创建一个Interface的对象,所以它抛出一个错误,我们可以通过以下方式实现根据您在GitHub中发布的解决方案

  • 添加Hashtable作为PostData方法的通用输入
  • 改变你的wallet.cs如下:

     IBalance CreateFactory(string typeOfBalance, string jsonString) { IBalance balance = null; switch (typeOfBalance) { case "balanceClassIdentification": balance = new Balance(); balance = Newtonsoft.Json.JsonConvert.DeserializeObject<Balance>(jsonString); break; case "": // write logic if Ibalance interface implemented in any childClass ex: class stockBalance: IBalance , then balance = new StockBalance();balance = Newtonsoft.Json.JsonConvert.DeserializeObject<stockBalance>(jsonString); default: balance = new Balance(); balance = Newtonsoft.Json.JsonConvert.DeserializeObject<Balance>(jsonString); break; } return balance; } private IDictionary<string, IBalance> GetBalances() { IDictionary<string, IBalance> data = null; var postData = new Dictionary<string, object>(); //var data = PostData<IDictionary<string, object>>("returnCompleteBalances", postData); Hashtable output = PostData<Hashtable>("returnCompleteBalances", postData); if (output.Count > 0) { data = new Dictionary<string, IBalance>(); } foreach (string jsonObjKey in output.Keys) { IBalance balace = CreateFactoty("balanceClassIdentification", output[jsonObjKey].ToString()); // this "balanceClassIdentification" just used as a string but we can add the condition in createFactory according to the type of object that wallet data.Add(jsonObjKey, balace); } return data; } 

  • 创建另一个实现Ibalance的中间类
  • 喜欢

     public class BalanceBase: IBalace { } 

    需要改变平衡等级

     private IDictionary<string, Balance> GetBalances()
            {
    
                var postData = new Dictionary<string, object>();
                var data = PostData<IDictionary<string, Balance>>("returnCompleteBalances", postData);
    
                return data;
            }
    

  • 如果除了余额之外没有为IBalance实施其他类别
  • 您可以直接将GetBalance()方法的返回类型用作IDictionary并更改实现

      private IDictionary<string, Balance> GetBalances() { var postData = new Dictionary<string, object>(); var data = PostData<IDictionary<string, Balance>>("returnCompleteBalances", postData); return data; } 

    暂无
    暂无

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

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