locked
How can I verify a type passed to a method matches the signature type? RRS feed

  • Question

  • My original problem starts in PowerShell, but, I am using .NET to trace the actual issue. I instantiated a new instance of a web service proxy using the New-WebServiceProxy cmdlet. I then created a type from the proxy stud and attempted to pass the object to a method, but, received an error. I am trying to validate that the typed object passed as an argument matches the type in the parameter. How might I do this in .NET? Assume this is a C# application and ignore the PowerShell dimension for a second.  

    To attempt to pin this down I looked at the underlying types and found the MetadataTokens for the argument and the parameter types do not match. But, I am not sure if this is relevant to the issue at hand. Another question (or another way I am asking the same question) is: what pieces of metadata does .NET look at to validate an argument type against a parameter's type?

    Thursday, July 12, 2012 6:39 PM

Answers

  • The basic answer is that if you have a type Foo and your method takes parameter type Bar then Foo needs to either derive from Bar (possibly indirectly) or if Bar is an interface, it needs to implement Bar (again could be indirect).

    If you were writing the code in C# you would get a compile time error if the argument isn't assignable to parameter type. For checks that you can do at runtime you can either cast, or use reflection:

    using System;
    using System.Diagnostics;
    
    namespace ConsoleApplication3
    {
        interface Bar
        { }
    
        class Foo
        { }
    
        class Program
        {
            static void Main(string[] args)
            {
                
                Foo f = new Foo();
    
                // this will throw InvalidCastException
                try
                {
                    Bar b = (Bar)f;
                } catch(InvalidCastException) {}
    
                // The assert will trigger because the types aren't assignment compatible
                Type typeOfBar = typeof(Bar);
                Type typeOfFoo = f.GetType();
                Debug.Assert(typeOfBar.IsAssignableFrom(typeOfFoo));
    
                // This is an alternative way of getting the type of Bar if you only know
                // which method uses the parameter but not the type of the parameter
                typeOfBar = typeof(Program).GetMethod("SomeMethod").GetParameters()[0].ParameterType;
                Debug.Assert(typeOfBar.IsAssignableFrom(typeOfFoo));
            }
    
            public void SomeMethod(Bar b) { } 
        }
    }
     

    As for what metadata gets used, that gets a bit complex and probably is too low level for your purposes. However if you are particularly curious the CLI ECMA specification has these details.

    HTH,

     -Noah

     

     

    Friday, July 13, 2012 3:20 AM