繁体   English   中英

在转换为接口时,对象必须实现IConvertible(InvalidCastException)

[英]Object must implement IConvertible (InvalidCastException) while casting to interface

我正在尝试将某种类型的对象转换为它使用Convert.ChangeType()实现的接口,但是由于该对象必须实现IConvertible ,因此会抛出InvalidCastException

类型:

public IDocumentSet : IQueryable {}

public IDocumentSet<TDocument> : IDocumentSet, IQueryable<TDocument> {}

public XmlDocumentSet<TDocument> : IDocumentSet<TDocument> {}

从发生错误的代码中摘录:

private readonly ConcurrentDictionary<Type, IDocumentSet> _openDocumentSets = new ConcurrentDictionary<Type, IDocumentSet>();

public void Commit()
{
    if (_isDisposed)
        throw new ObjectDisposedException(nameof(IDocumentStore));

    if (!_openDocumentSets.Any())
        return;

    foreach (var openDocumentSet in _openDocumentSets)
    {
        var documentType    = openDocumentSet.Key;
        var documentSet     = openDocumentSet.Value;

        var fileName        = GetDocumentSetFileName(documentType);
        var documentSetPath = Path.Combine(FolderPath, fileName);

        using (var stream = new FileStream(documentSetPath, FileMode.Create, FileAccess.Write))
        using (var writer = new StreamWriter(stream))
        {
            var documentSetType     = typeof (IDocumentSet<>).MakeGenericType(documentType);
            var writeMethod         = typeof (FileSystemDocumentStoreBase)
                                        .GetMethod(nameof(WriteDocumentSet), BindingFlags.Instance | BindingFlags.NonPublic)
                                        .MakeGenericMethod(documentSetType);
            var genericDocumentSet  = Convert.ChangeType(documentSet, documentSetType); <-------

            writeMethod.Invoke(this, new[] {writer, genericDocumentSet});
        }
    }
}

现在,我无法理解为什么会发生这种情况(因为XmlDocumentSet不是值类型)并且XmlDocumentSet<'1>实现了IDocumentSet<'1> 我错过了什么吗? 或者有更简单的方法来实现我正在做的事情?

IConvertible接口旨在允许类安全地将自身转换为另一个类型。 Convert.ChangeType调用使用该接口将一种类型安全地转换为另一种类型。

如果您在编译时不知道类型,那么您将被迫尝试运行时强制转换。 这是在一个非常类似的问题中讨论这里将变量转换为仅在运行时已知的类型?

对于这种合法的场景,实现IConvertible是一件很痛苦的事情,在我看来浪费了宝贵的开发时间。 最好是在基类中实现一个抽象方法,派生类将实现该方法以返回自身。 下面是一个例子。

//implement this in base class
        protected abstract BaseDocumentTypeMap<ID> ConvertDocType(T doc);

//usage of the abstract code
            BaseDocumentTypeMap<ID> beDocType;

                //loop through all the document types and check if they are enabled
                foreach(T doc in result)
                {
                    beDocType = ConvertDocType(doc);
                    //some action
                }


//implement this in the derived class
        protected override BaseDocumentTypeMap<int> ConvertDocType(DocumentTypeMap doc)
        {
            return doc;
        }

这项工作完美无需痛苦的IConvertible。 在上面的示例中,基类使用<ID, T>实现接口,派生类具有对DocumentTypeMap类的引用,而DocumentTypeMap类正在使用<ID>实现接口

暂无
暂无

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

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