在接受界面参数(C#,MVC)时,对象的对象进行了审理



给定接口:

interface IObject
{
   public string Name {get;set}   
}

和以下对象:

class A: IObject
{
   public string Name {get;set}
   public int ID {get;set;}
}
class B: IObject
{
   public string Name {get;set}
   public Guid ID {get;set;}
}

我有两个使用不同数据库模式的消费应用程序,但要做相同的工作。这是维护旧应用程序的问题,而团队则写一个新应用程序。要求包括两者都使用相同的库,这就是为什么存在此问题的原因。应用程序都调用相同的外部API,并且该调用在其自己的静态类中,并且可以像这样访问:

public static IEnumerable<IObject> List(Guid listUniqueIdentifier)
 {
       //a custom class to call the API
       using (var cmd = new WebApiCommand()) 
       {
                               //custom enum
             cmd.CommandType = ApiComType.GET;
             cmd.Command = "ListObjects";
             cmd.Filter = listUniqueIdentifier.ToString();
             IEnumerable<object> data = cmd.Execute();
             var result = new List<IObject>();
             foreach(var d in data)
             {
               result.add(JsonConvert.DeserializeObject<IObject>(Convert.ToString(d)));
             }
             return result;
       }   
}

显然,您无法实例化接口,所以

result.add(JsonConvert.DeserializeObject<IObject>(Convert.ToString(d)));

断裂。我不想只尝试构建指导版本,如果它失败了,请使用整数版本。不仅有点骇客,而且是使用整数的新数据库,因此我会以更糟糕的方式使用try块作为流控制。在不为每种类型编写不同的方法的情况下,如何对正确的对象实例类型(A或B)进行应对序列化?编辑:我发现的解决方案通常涉及序列化$类型或以其他方式保存序列化的实例类型。这是不可能的,因为API已连接到第三方应用程序并且无法存储此基准。

您可以使用自定义JsonConverter检测ID的类型,然后在测试过程中实例化并填充正确的对象类型:

class CustomIObjectConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(IObject).IsAssignableFrom(objectType);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        IObject target;
        if (jo["ID"].Type == JTokenType.Integer)
        {
            target = Activator.CreateInstance<A>();
        }
        else  // Guid
        {
            target = Activator.CreateInstance<B>();
        }
        serializer.Populate(jo.CreateReader(), target);
        return target;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,只需将其实例传递给DeserializeObject()

var converter = new CustomIObjectConverter();
...
foreach(var d in data)
{
    result.add(JsonConvert.DeserializeObject<IObject>(Convert.ToString(d), converter));
}

这是一个简短的演示,可以证明以下概念:https://dotnetfiddle.net/p2hzsl

据我所知,

您的问题是,您无法通过" D"识别哪种类型的类别序列化。(伪)

foreach(var d in data)
    {
       like if(Convert.ToString(d).All(char.IsDigit) && Convert.ToString(d).length <= Int32.MaxValue)
       {
          result.add(JsonConvert.DeserializeObject<A>(Convert.ToString(d)));
       }
       else
       {
          result.add(JsonConvert.DeserializeObject<B>(Convert.ToString(d)));
       }
    }

编辑:我认为这是您提供的有限信息的最佳方法。如果不是,我建议您更改数据调用本身,因此WebAPI可以根据可能的情况为您提供两套不同的数据。

我能想到的一种方法是添加您首先值得注意的内部助手类,然后从那里生成您的 AB对象。这样的东西(注意:我假设您的GUID没有分离器字符)。

internal class Helper
{
    public string _name {get;set;}
    public string _id {get;set;}
    public IObject GetAOrBObject()
    {
        if (_id.Length == 32) // Assume GUID with no separator like '-'
        {
            return new A() { Name = _name, ID = Guid.Parse(_id) };
        }
        else
        {
            return new B() { Name = _name, ID = int.Parse(_id) };
        }
    }
}

然后,您可以将循环中的代码更改为:

foreach(var d in data)
{
    var temp = JsonConvert.DeserializeObject<Helper>(Convert.ToString(d)));
    result.add(temp.GetAOrBObject());
}
return result;

相关内容

  • 没有找到相关文章

最新更新