c# - 无法将对象转换为其类型

标签 c# casting

我有一个具有对象类型输入的函数。该函数的值是一个名为“Box”的类的数组,我已经进行了以下尝试,但无法转换 object valueBox[] .

    internal class BoxConverter : IRunDataConverter
    {
        string IRunDataConverter.Key => "boxes";

        object IRunDataConverter.ConvertToPublishable(object value)
        {
            //return value;

            object[] arr = (object[])value;//value is an array of Box

            System.Diagnostics.Debug.WriteLine(arr[0].GetType());// --> WF.CV.Entity.Box
            System.Diagnostics.Debug.WriteLine(typeof(Box));//      --> WF.CV.Entity.Box

            System.Diagnostics.Debug.WriteLine(arr[0].GetType().AssemblyQualifiedName);// --> WF.CV.Entity.Box, WF.CV, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
            System.Diagnostics.Debug.WriteLine(typeof(Box).AssemblyQualifiedName);//      --> WF.CV.Entity.Box, WF.CV, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 

            bool sameTypes = typeof(Box) == arr[0].GetType();// FALSE



            Box[] try1 = arr.OfType<Box>().ToArray();// try1 -> array with zero lenght.

            Box[] boxes = new Box[arr.Length];
            for(int i=0; i<arr.Length; i++)
            {
                Box box = (Box)arr[i]; // Error:
                                       // System.InvalidCastException:
                                       // '[A]WF.CV.Entity.Box cannot be cast to
                                       //  [B]WF.CV.Entity.Box. Type A originates from 'WF.CV, Version=1.0.0.0,
                                       //           Culture=neutral, PublicKeyToken=null' in the context 'Default' at
                                       //           location 'C:\_koray\korhun\WF\WF.Web\bin\Debug\net5.0\WF.CV.dll'.
                                       //  Type B originates from 'WF.CV, Version=1.0.0.0,
                                       //           Culture=neutral, PublicKeyToken=null' in the context 'Default' in a byte array.'




                dynamic val = new System.Dynamic.ExpandoObject();
                val.Name = box.Name;
                val.Confidence = box.Confidence;
                val.Coords = box.Coords;
                boxes[i] = val;
            }
            return boxes;
        }
    }

当我输入typeof(Box)时和arr[0].GetType()进入立即窗口我得到以下结果。 (图中未见的部分是相同的。) enter image description here

这是 Box 类:

using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
    
namespace WF.CV.Entity
{
    [DebuggerDisplay("Name: {Name} Confidence: {Confidence} Location: {Location}")]
    public class Box
    {
        public string Name { get; set; }
        public float Confidence { get; set; }
    
        /// <summary>
        /// Normalized MinX, MinY, MaxX, MaxY
        /// </summary>
        public float[] Coords { get; set; }
    
        [JsonIgnore]
        public float Left => Coords[0];
        [JsonIgnore]
        public float Right => Coords[2];
        [JsonIgnore]
        public float Top => Coords[1];
        [JsonIgnore]
        public float Bottom => Coords[3];
    
        [JsonIgnore]
        public float Width => Coords[2] - Coords[0];
        [JsonIgnore]
        public float Height => Coords[3] - Coords[1];
    
    
        public Rect GetRect(int width, int height)
        {
            int x = (int)(Coords[0] * width);
            int y = (int)(Coords[1] * height);
            int w = (int)((Coords[2] - Coords[0]) * width);
            int h = (int)((Coords[3] - Coords[1]) * height);
            return new Rect(x, y, w, h);
        }
    
    }
}

这种情况发生在 Visual Studio 2019、Windows 10 环境中 Entity Framework 和 Web API 项目使用的不安全 dll 内。所有项目的目标框架都是.NET 5.0。

更新 - 之前发生了什么:

IRunDataConverter 正在使用此管理器类进行调用。它位于非不安全的 dll 中:

public class RunDataConverterManager : IRunDataConverterManager
{
    private readonly ILogger<IRunDataConverter> logger;
    private readonly IServiceProvider provider;

    public RunDataConverterManager(ILogger<IRunDataConverter> logger, IServiceProvider provider)
    {
        this.logger = logger;
        this.provider = provider;
        initialize();
    }

    private Dictionary<string, IRunDataConverter> converters;
    private void initialize()
    {
        this.converters = new Dictionary<string, IRunDataConverter>();

        string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        foreach (string dll in Directory.GetFiles(path, "*.dll"))
            AppDomain.CurrentDomain.Load(File.ReadAllBytes(dll));

        var type = typeof(IRunDataConverter);
        var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => type.IsAssignableFrom(p) && p.IsClass);

        HashSet<string> hs = new();
        foreach (Type ty in types)
            if (hs.Add(ty.AssemblyQualifiedName))
            {
                IRunDataConverter converter = null;
                try
                {
                    converter = create(ty);
                }
                catch (Exception ex)
                {
                    this.logger.LogError($"Cannot create IRunDataConverter! assemblyName: {ty.AssemblyQualifiedName} typeName: {ty.Name} exception: {ex.GetLogMessage()}");
                }
                if (converter != null)
                {
                    if (this.converters.ContainsKey(converter.Key))
                        throw new Exception($"Duplicated key for IRunDataConverter! There can be only one converter for a key. Key: {converter.Key}");
                    else
                        this.converters.Add(converter.Key, converter);
                }
            }
    }
    private IRunDataConverter create(Type ty)
    {
        //ref: https://stackoverflow.com/a/34746583/1266873
        return (IRunDataConverter)ActivatorUtilities.CreateInstance(this.provider, ty);
    }



    IRunDataPublishable[] IRunDataConverterManager.ConvertToPublishable(RunData[] data)
    {
        return this.getData(data).ToArray();
    }
    private IEnumerable<IRunDataPublishable> getData(RunData[] data)
    {
        Dictionary<string, List<object>> dic = new();
        if (data != null)
            foreach (RunData item in data)
                if (item != null)
                {
                    //this is where it's called
                    object value = this.converters.ContainsKey(item.Key) ? this.converters[item.Key].ConvertToPublishable(item.Value) : item.Value;
                    if (!dic.ContainsKey(item.Key))
                        dic.Add(item.Key, new List<object>() { value });
                    else
                        dic[item.Key].Add(value);
                }
        foreach (string key in dic.Keys)
            yield return new runData()
            {
                Key = key,
                Values = dic[key].ToArray()
            };
    }
    private class runData : IRunDataPublishable
    {
        public string Key { get; set; }
        public object[] Values { get; set; }
    }
}


//RunData class is in another non-unsafe dll:
[DebuggerDisplay("Key: {Key} Value: {Value}")]
    public class RunData
    {
        public RunnerNode Node { get; set; }
        public string Key { get; set; }
        public object Value { get; set; }

        public RunDataDictionary Children { get; private set; } = new RunDataDictionary();

        public RunData(RunnerNode node, string key, object value)
        {
            this.Node = node; 
            this.Key = key;
            this.Value = value;
        }

        public RunData Clone()
        {
            return new RunData(this.Node, this.Key, this.Value)
            {
                Children = this.Children.Clone()
            };
        }
    }

IRunDataConverterManager 是一个单例注入(inject)项(Startup/ConfigureServices/ services.AddSingleton<IRunDataConverterManager, RunDataConverterManager>(); )

RunData 项,这些值不会以任何方式序列化-反序列化,直到我在 BoxConverter.ConvertToPublishable 中遇到问题为止。方法。

最佳答案

请更改下面的代码。

AppDomain.CurrentDomain.Load(File.ReadAllBytes(dll)) -> AppDomain.CurrentDomain.Load(Assembly.LoadFrom(dll).GetName());

关于c# - 无法将对象转换为其类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67600330/

相关文章:

c++ - 将 vector<Derived*> 转换为 vector<Base*> 时如何避免复制

inheritance - 在 Actionscript 中转换为子类

ios - 快速类型转换性能成本

c++ - 从基指针集合转换为子类

c# - C#(.Net) 编译器和 Java 编译器技术之间有什么区别?

c# - 从 C#/WCF 使用 Java 服务 - 数组仅对编码的 SOAP 有效

c# - 使用 XmlReaderSettings.Schemas 并指定要使用的多个架构时性能下降

c# - 内联条件 c# - 下一个最佳解决方案?

c# - 如何在 Simple.Data 中使用 sql 函数(合并或 isnull)

c# - 如何查看邮件是否发送成功?