Использование подкласса DataObject в качестве буфера обмена DataObject

Когда я попробую следующее, результаты будут неожиданными. Любые идеи будут оценены по достоинству!

    Class DataObjectSub
        Inherits DataObject

    End Class

    Sub Test()

        Dim myObject = New DataObjectSub

        myObject.SetData("Test")
        Clipboard.SetDataObject(myObject)

        Dim myRetrievedObject As IDataObject = Clipboard.GetDataObject
        Console.Write(myRetrievedObject.GetType.ToString)

        Dim myRetrievedObject2=TryCast(Clipboard.GetDataObject,DataObjectSub)

    End Sub

myRetrievedObject2 - это ничто

Выходные данные оператора Write: "System.Windows.Forms.DataObject". Разве это не должно быть "DataObjectSub"? Я что-то упускаю из виду?

Отредактировано по запросу:

В случае операций перетаскивания, этот DataObject (реализующий iDataObject) снова используется, можно сделать это:

Sub TestDragDrop

Dim myObject as iDataObject=new DataObjectSub

someControl.DoDragDrop(myObject, myAllowedEffects)

End Sub

Позже... в обработчике события DragOver:

Sub anotherControl_DragOver(sender as object, e as DragEventArgs)

Dim myRetrievedObject1 as DataObjectSub = TryCast(e.Data, DataObjectSub)
Dim myRetrievedObject2 as IDataObject = e.Data


End Sub

работает хорошо, и myRetrievedObject1 и myRetrievedObject2 не являются ничем. Типы обоих извлеченных объектов: DataObjectSub.

Спасибо за любые идеи и терпение!:)

1 ответ

Это не неожиданное поведение. Clipboard.GetDataObject просто хранит данные в Clipboard (как указано в MSDN) и его тип DataObject (как указано в вашем коде). Когда вы проверяете его тип, не имеет значения, является ли входная переменная DataObject или любой другой тип (поддерживается GetDataObject). Имейте в виду, что GetDataObject является методом, возвращаемое значение которого не должно следовать правилам назначения по умолчанию (т. е. его вызов не вызывает тех же эффектов, что и назначение String переменная к Object переменная, например).

Этот код:

Dim myString As String = "Test"
Clipboard.SetDataObject(myString)
Dim myRetrievedObject As IDataObject = Clipboard.GetDataObject
Console.Write(myRetrievedObject.GetType.ToString)

выводит точно такой же результат, как и ваш код. myRetrievedObject.GetType.ToString просто проверяет тип GetDataObject, который всегда DataObject,

ОБНОВИТЬ

После нашего обсуждения я хочу уточнить, что Clipboard.GetDataObject возвращает IDataObject переменная (интерфейс DataObject, не другого типа). Пример кода, чтобы понять все это:

Dim myRetrievedObject1 As IDataObject = Clipboard.GetDataObject
Dim myRetrievedObject2 As DataObject = New DataObject(Clipboard.GetDataObject)
Dim myRetrievedObject3 As DataObject = DirectCast(Clipboard.GetDataObject, DataObject)
Dim test4 As DataObject = New DataObject

If (TypeOf myRetrievedObject1 Is DataObject AndAlso TypeOf myRetrievedObject2 Is DataObject AndAlso TypeOf myRetrievedObject3 Is DataObject AndAlso TypeOf test4 Is DataObject) Then
    'Condition is met
End If
If (TypeOf myRetrievedObject1 Is IDataObject AndAlso TypeOf myRetrievedObject2 Is IDataObject AndAlso TypeOf myRetrievedObject3 Is IDataObject AndAlso TypeOf test4 Is IDataObject) Then
    'Condition is met
End If

Как вы можете видеть (два условия выполнены, что означает, что все переменные имеют тип DataObject а также IDataObject в то же время), отношения DataObject / IDataObject не похож на тот, что между двумя разными типами. На самом деле, как показано myRetrievedObject3 кастинг - это просто формальное требование (я кастую DataObject переменная к DataObject!). DataObject / IDataObject в основном две стороны одной медали (которая называется DataObject) Это подразумевает, что условие ниже верно:

Dim Type1 As String = myRetrievedObject1.GetType().ToString()
Dim Type2 As String = myRetrievedObject2.GetType().ToString()
Dim Type3 As String = myRetrievedObject3.GetType().ToString()
Dim Type4 As String = test4.GetType().ToString()

If (Type1 = Type2 AndAlso Type1 = Type3 AndAlso Type1 = Type4 AndAlso Type1 = GetType(DataObject).ToString) Then
    'Condition is met
End If

То есть имя типа для обоих DataObject а также IDataObject переменные DataObject (или, точнее: System.Windows.Forms.DataObject).

Другие вопросы по тегам