簡體   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