将对象转换为 ValueTuple

Sup*_*JMN 0 .net c# casting tuples

给定类 Page (UWP) 的 OnNavigatedTo 方法

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        if (e.Parameter != null)
        {
            var o = (ValueTuple<object, object>) e.Parameter;
            Content = (UIElement) o.Item1;
            this.DataContext = o.Item2;
        }

        base.OnNavigatedTo(e);
    }
Run Code Online (Sandbox Code Playgroud)

我想将e.Parameter(对象类型)转换为ValueTuple<object, object>.

该参数携带我想作为Frame.Navigate这样的调用的一部分过去的实例:

Frame.Navigate(typeof(SomePage), (view, viewModel));

演员阵容应该有效。它应该是安全的,因为我认为ValueTuple<X, Y>应该可以转换为ValueTuple<object, object>,对吗?

但是,它会抛出一个Invalid Cast Exception

选角有什么问题?

如何从object包含元组实例的类型引用转换为对元组的类型化引用?

附加信息

抛出的确切异常是这样的:

System.InvalidCastException: '无法转换类型为'System.ValueTuple 2[System.Object,Reflight.Gui.ViewModels.FlightGalleryViewModel]' to type 'System.ValueTuple2[System.Object,System.Object]'的对象。'

e.Parameter.GetType() 输出这个:

{Name = "ValueTuple 2" FullName = "System.ValueTuple2[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Reflight.Gui.ViewModels.FlightGalleryViewModel, Reflight.Gui.ViewModels, Version= 1.0.0.0,Culture=neutral,PublicKeyToken=null]]"} 程序集:{System.Private.CoreLib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=7cec85d7bea7798e}AssemblyQualifiedName:“System.ValueTuple2[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Reflight.Gui.ViewModels.FlightGalleryViewModel, Reflight.Gui.ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" Attributes: Public | Sealed | Serializable | BeforeFieldInit BaseType: {Name = "ValueType" FullName = "System.ValueType"} ContainsGenericParameters: false CustomAttributes: Count = 2 DeclaredConstructors: {System.Reflection.ConstructorInfo[1]} DeclaredEvents: {System.Reflection.EventInfo[0]} DeclaredFields: {System.Reflection.FieldInfo[2]} DeclaredMembers: {System.Reflection.MemberInfo[19]} DeclaredMethods: {System.Reflection.MethodInfo[14]} DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22} DeclaredProperties: {System.Reflection.PropertyInfo[2]} DeclaringMethod: '((System.RuntimeType)e.Parameter.GetType()).DeclaringMethod' threw an exception of type 'System.InvalidOperationException' DeclaringType: null FullName: "System.ValueTuple2[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Reflight.Gui.ViewModels.FlightGalleryViewModel, Reflight.Gui.ViewModels, Version=1.0.0.0, Culture =neutral, PublicKeyToken=null]]" GUID: {4a04084c-cb2b-378d-aa9c-a77abd9ba77e} GenericParameterAttributes: '((System.RuntimeType)e.Parameter.GetType()).GenericParameterAttributes' 抛出了一个类型为 'System. InvalidOperationException' GenericParameterPosition: '((System.RuntimeType)e.Parameter.GetType()).GenericParameterPosition' 抛出了一个类型为 'System.InvalidOperationException' 的异常 GenericTypeArguments: {System.Type[2]} GenericTypeParameters: {System.Type[0] ]} HasElementType: false 实现接口: {System.Type[7]} IsAbstract:false IsAnsiClass: true IsArray: false IsAutoClass: false IsAutoLayout: true IsByRef: false IsByRefLike: false IsCOMObject: false IsClass: false IsCollectible: false IsConstructedGenericType: true IsContextful: false IsEnum: false IsExplicitLayout: false IsGenericMethodParameter: false IsGenericParameter: false IsGenericType: true IsGenericType : false IsGenericTypeParameter: false IsImport: false IsInterface: false IsLayoutSequential: false IsMarshalByRef: false IsNested: false IsNestedAssembly: false IsNestedFamANDAssem: false IsNestedFamORAssem: false IsNestedFamily: false IsNestedPrivate: false IsNestedPublicPfalse IsPrimitive: false IsPublic: true IsSZArray: false IsSealed: true IsSecurityCritical: true IsSecuritySafeCritical: false IsSecurityTransparent: false IsSerializable: true IsSignatureType: false IsSpecialName: false IsTypeDefinition: false IsUnicodeClass: false IsValueType: true IsVariableBoundArray: false IsVisible: true MetadataTokenType: :33554856 模块(System.Reflection.MemberInfo):{System.Private.CoreLib.dll} 模块:{System.Private.CoreLib.dll} 名称:“ValueTupletrue IsSignatureType: false IsSpecialName: false IsTypeDefinition: false IsUnicodeClass: false IsValueType: true IsVariableBoundArray: false IsVisible: true MemberType: TypeInfo MetadataToken: 33554856 Module (System.Reflection.MemberInfo): {System.Private.CoreLib.dll} Module: {System .Private.CoreLib.dll} 名称:"ValueTupletrue IsSignatureType: false IsSpecialName: false IsTypeDefinition: false IsUnicodeClass: false IsValueType: true IsVariableBoundArray: false IsVisible: true MemberType: TypeInfo MetadataToken: 33554856 Module (System.Reflection.MemberInfo): {System.Private.CoreLib.dll} Module: {System .Private.CoreLib.dll} 名称:"ValueTuple2" Namespace: "System" ReflectedType: null StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute} TypeHandle: {System.RuntimeTypeHandle} TypeInitializer: null UnderlyingSystemType: {Name = "ValueTuple2" FullName = "System.ValueTuple`2[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Reflight.Gui.ViewModels.FlightGalleryViewModel, Reflight.Gui. ViewModels, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}

Jon*_*eet 11

如何从包含元组实例的类型对象的引用转换为对元组的类型化引用?

您必须转换为正确的元组类型。您正在将 a 转换ValueTuple<MyClass, object>为 a ValueTuple<object, object>,它们是不同的类型。

这工作正常,例如:

using System;

class Test
{
    static void Main()
    {
        object obj = ("foo", "bar");
        // Casting to the right type works... but a cast to
        // ValueTuple<object, object> would fail.
        var tuple = (ValueTuple<string, string>) obj;
        Console.WriteLine(tuple.Item1); // foo
        Console.WriteLine(tuple.Item2); // bar
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想要一个ValueTuple<object, object>你可以这样做,当然:

object myTuple = ((object) instance, new object());
Run Code Online (Sandbox Code Playgroud)

如果您想引用任何值元组,您可以(不幸的是,取决于您所针对的框架)能够使用ITuple

using System;
using System.Runtime.CompilerServices;

class Test
{
    static void Main()
    {
        object obj = ("foo", 10);
        var tuple = (ITuple) obj;

        for (int i = 0; i < tuple.Length; i++)
        {
            Console.WriteLine(tuple[i]); // foo then 10
        }
    }
}
Run Code Online (Sandbox Code Playgroud)