[c#] प्रतिबिंब: पैरामीटर के साथ विधि कैसे शामिल करें



Answers

आपके पास वहां एक बग है

result = methodInfo.Invoke(methodInfo, parametersArray);

यह होना चाहिए

result = methodInfo.Invoke(classInstance, parametersArray);
Question

मैं पैरामीटर के साथ प्रतिबिंब के माध्यम से एक विधि का आह्वान करने की कोशिश कर रहा हूं और मुझे मिलता है:

ऑब्जेक्ट लक्ष्य प्रकार से मेल नहीं खाता है

अगर मैं पैरामीटर के बिना एक विधि का आह्वान करता हूं, तो यह ठीक काम करता है। यदि मैं विधि Test("TestNoParameters") कॉल करता हूं, तो निम्न कोड के आधार पर, यह ठीक काम करता है। हालांकि अगर मैं Test("Run") कहता हूं, तो मुझे अपवाद मिलता है। क्या मेरे कोड में कुछ गड़बड़ है?

मेरा प्रारंभिक उद्देश्य ऑब्जेक्ट्स की एक सरणी को पार करना था जैसे public void Run(object[] options) लेकिन यह काम नहीं करता था और मैंने सफलता के बिना स्ट्रिंग जैसे कुछ आसान प्रयास किया।

// Assembly1.dll
namespace TestAssembly
{
    public class Main
    {
        public void Run(string parameters)
        { 
            // Do something... 
        }
        public void TestNoParameters()
        {
            // Do something... 
        }
    }
}

// Executing Assembly.exe
public class TestReflection
{
    public void Test(string methodName)
    {
        Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
        Type type = assembly.GetType("TestAssembly.Main");

        if (type != null)
        {
            MethodInfo methodInfo = type.GetMethod(methodName);

            if (methodInfo != null)
            {
                object result = null;
                ParameterInfo[] parameters = methodInfo.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);

                if (parameters.Length == 0)
                {
                    // This works fine
                    result = methodInfo.Invoke(classInstance, null);
                }
                else
                {
                    object[] parametersArray = new object[] { "Hello" };

                    // The invoke does NOT work;
                    // it throws "Object does not match target type"             
                    result = methodInfo.Invoke(methodInfo, parametersArray);
                }
            }
        }
    }
}



 Assembly assembly = Assembly.LoadFile(@"....bin\Debug\TestCases.dll");
       //get all types
        var testTypes = from t in assembly.GetTypes()
                        let attributes = t.GetCustomAttributes(typeof(NUnit.Framework.TestFixtureAttribute), true)
                        where attributes != null && attributes.Length > 0
                        orderby t.Name
                        select t;

        foreach (var type in testTypes)
        {
            //get test method in types.
            var testMethods = from m in type.GetMethods()
                              let attributes = m.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), true)
                              where attributes != null && attributes.Length > 0
                              orderby m.Name
                              select m;

            foreach (var method in testMethods)
            {
                MethodInfo methodInfo = type.GetMethod(method.Name);

                if (methodInfo != null)
                {
                    object result = null;
                    ParameterInfo[] parameters = methodInfo.GetParameters();
                    object classInstance = Activator.CreateInstance(type, null);

                    if (parameters.Length == 0)
                    {
                        // This works fine
                        result = methodInfo.Invoke(classInstance, null);
                    }
                    else
                    {
                        object[] parametersArray = new object[] { "Hello" };

                        // The invoke does NOT work;
                        // it throws "Object does not match target type"             
                        result = methodInfo.Invoke(classInstance, parametersArray);
                    }
                }

            }
        }



प्रदत्त समाधान रिमोट असेंबली से लोड किए गए प्रकारों के उदाहरणों के लिए काम नहीं करता है। ऐसा करने के लिए, यहां एक समाधान है जो सभी परिस्थितियों में काम करता है, जिसमें CreateInstance कॉल के माध्यम से लौटाए गए प्रकार का एक स्पष्ट प्रकार पुन: मैपिंग शामिल है।

इस तरह मुझे अपनी कक्षा स्थापना बनाने की ज़रूरत है, क्योंकि यह एक दूरस्थ असेंबली में स्थित था।

// sample of my CreateInstance call with an explicit assembly reference
object classInstance = Activator.CreateInstance(assemblyName, type.FullName); 

हालांकि, ऊपर दिए गए उत्तर के साथ भी, आपको अभी भी वही त्रुटि मिल जाएगी। यहां बताया गया है कि कैसे जाना है:

// first, create a handle instead of the actual object
ObjectHandle classInstanceHandle = Activator.CreateInstance(assemblyName, type.FullName);
// unwrap the real slim-shady
object classInstance = classInstanceHandle.Unwrap(); 
// re-map the type to that of the object we retrieved
type = classInstace.GetType(); 

फिर यहां उल्लेखित अन्य उपयोगकर्ताओं के रूप में करें।




Links