Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过反射调用具有类参数的方法_C#_.net_Reflection - Fatal编程技术网

C# 通过反射调用具有类参数的方法

C# 通过反射调用具有类参数的方法,c#,.net,reflection,C#,.net,Reflection,我刚从C#反射开始,遇到了调用以内部类为参数的方法的问题: 示例类: public class MyClass { public class CustomColor { public int h; public int s; public int v; } public string[] ConvertColors(List<CustomColor> colors) { //

我刚从C#反射开始,遇到了调用以内部类为参数的方法的问题:

示例类:

public class MyClass 
{
    public class CustomColor 
    {
        public int h;
        public int s;
        public int v;
    }

    public string[] ConvertColors(List<CustomColor> colors)
    {
        //...
    }
}
允许我这样做:

myClassObject.SomeSampleMethod(int sampleParam);

但是,我一直在思考如何为上面的ConvertColor方法创建正确的参数:(

我不确定您是如何创建的
cInstanceContainerObject
。我正在使用
MethodInfo.Invoke
。下面是代码:

//Your class
public class MyClass 
{
    public class CustomColor 
    {
        public int h;
        public int s;
        public int v;
    }

    public string[] ConvertColors(List<CustomColor> colors)
    {
        return new string[]{"1"};
    }
}

//Usage
MyClass mc = new MyClass();
    MyClass.CustomColor cc = new MyClass.CustomColor();

    Type t = mc.GetType();
    MethodInfo mi = t.GetMethod("ConvertColors");
    List<MyClass.CustomColor> lst = new List<MyClass.CustomColor>
    {   
        new MyClass.CustomColor(),
        new MyClass.CustomColor()
    };
    var x = (string[])mi.Invoke(mc,new object[]{lst});
    Console.WriteLine (x.Count());
//您的类
公共类MyClass
{
公共类自定义颜色
{
公共INTH;
公共INTS;
公共INTV;
}
公共字符串[]转换颜色(列表颜色)
{
返回新字符串[]{“1”};
}
}
//用法
MyClass mc=新的MyClass();
MyClass.CustomColor cc=新的MyClass.CustomColor();
类型t=mc.GetType();
MethodInfo mi=t.GetMethod(“ConvertColor”);
列表lst=新列表
{   
新建MyClass.CustomColor(),
新建MyClass.CustomColor()
};
var x=(字符串[])mi.Invoke(mc,新对象[]{lst});
Console.WriteLine(x.Count());
汤姆

尝试传递要转换的颜色作为参考

在下面的示例中,作为引用传入的颜色(CustomColor)将被更新,而不是返回字符串

因此,不要像这样调用方法:

string[] colors = ConvertColors(yourColorList, foo, bar);
它可以称为:

ConvertColors(yourColorList, foo, bar);
例如:

public class MyClass
{
    public class CustomColor
    {
        public int h;
        public int s;
        public int v;
    }

    public enum Convert { H, S, V, HS, HV, SV, HSV };

    public void ConvertColors(ref List<CustomColor> colors, Convert type,
        ref CustomColor changeAmt)
    {
        // Variables to change H, S, and V from changeAmt parameter:
        int changeH = changeAmt.h;
        int changeS = changeAmt.s;
        int changeV = changeAmt.v;

        // Change the actual colors which were passed as 'colors' parameter.
        switch (type)
        {
            // Change H.
            case Convert.H:
                foreach (CustomColor c in colors)
                    c.h += changeH;
                break;

            // Change S.
            case Convert.S:
                foreach (CustomColor c in colors)
                    c.s += changeS;
                break;

            // Change V.
            case Convert.V:
                foreach (CustomColor c in colors)
                    c.v += changeV;
                break;

            // Change HS.
            case Convert.HS:
                foreach (CustomColor c in colors)
                {
                    c.h += changeH;
                    c.s += changeS;
                }
                break;

            // Change HV.
            case Convert.HV:
                foreach (CustomColor c in colors)
                {
                    c.h += changeH;
                    c.v += changeV;
                }
                break;

            // Change SV.
            case Convert.SV:
                foreach (CustomColor c in colors)
                {
                    c.s += changeS;
                    c.v += changeV;
                }
                break;

            // Change HSV.
            case Convert.HSV:
                foreach (CustomColor c in colors)
                {
                    c.h += changeH;
                    c.s += changeS;
                    c.v += changeV;
                }
                break;
        }
    }
}
“switch”语句允许您处理这些参数:

switch (type)
        {
            case Convert.H:
                // Do something
                return;
            case Convert.S:
                // Do something
                return;
            case Convert.V:
                // Do something
                return;
创建要作为新CustomColor进行的更改的实例,并将对CustomColor列表的引用、自定义参数以及对更改的引用作为CustomColor传递:

private void AnyMethod()
    {
        // Create first custom color.
        CustomColor color1 = new CustomColor();
        color1.h = 50;
        color1.s = 25;
        color1.v = 35;

        // Create second custom color.
        CustomColor color2 = new CustomColor();
        color2.h = 50;
        color2.s = 25;
        color2.v = 35;

        // Create third custom color.
        CustomColor color3 = new CustomColor();
        color3.h = 50;
        color3.s = 25;
        color3.v = 35;

        // Add to list of custom colors.
        List<CustomColor> colorList = new List<CustomColor>();
        colorList.Add(color1);
        colorList.Add(color2);
        colorList.Add(color3);

        // Create changes as a new color.
        CustomColor colorChange = new CustomColor();
        colorChange.h = -10;
        colorChange.s = 47;
        colorChange.v = -15;

        // Update all colors in your list.
        ConvertColors(ref colorList, Convert.HSV, ref colorChange); // BOOM.
    }

经过一个不眠之夜,我终于找到了实现的方法。这两个答案确实帮助我看到了找到答案的可能性,但是我必须在不引用外部DLL或对其进行任何修改的情况下实现这一点,只需通过反射获取其主对象的一个实例,然后调用I中的各种方法t(在我的示例中可以看到,其中一些必需的类仅由DLL本身提供)

我的解决方案如下(请随意提供更好的替代方案):

通过使用方法参数,分别获取列表和CustomColor的类型:

Type listType = myClassObject.GetType()
                             .GetMethod("ConvertColors")
                             .GetParameters()[0]
                             .ParameterType;

Type colorType = myClassObject.GetType()
                 .GetMethod("ConvertColors")
                 .GetParameters()[0]
                 .ParameterType
                 .GetProperty("Item")
                 .PropertyType;
然后使用Activator创建整个列表和单个CustomColor的单个实例:

dynamic colorList = Activator.CreateInstance(listType);
dynamic customColor = Activator.CreateInstance(colorType);
colorList.Add(customColor);

myClassObject.ConvertColors(colorList); //works!

你想调用ConvertColors吗?@singsuyash是的,我想调用ConvertColors,但我无法集中精力创建CustomColor的实例,然后列出它们并将其传递给我的invoke。你想要一个简单地使用
MethodInfo.invoke调用的答案吗?还是你在寻找其他东西。我不知道我不介意任何方法,只要我可以调用ConvertColors,而不会得到“MyClass.ConvertColors(System.Collections.Generic.List)”的最佳重载方法匹配有一些无效参数”:(现在请粘贴参数
colors
的实例化方式。该实例来自另一个DLL。当我尝试将其添加为引用并使用相同的列表时,我得到一个“调用动态方法时出现未知异常”是
cInstanceContainerObject
MyClass
CustomColor
的实例?
string[] hsvStrings =
        {
            color1.h.ToString(),
            color1.s.ToString(),
            color1.v.ToString(),
            // Continue...
        };
Type listType = myClassObject.GetType()
                             .GetMethod("ConvertColors")
                             .GetParameters()[0]
                             .ParameterType;

Type colorType = myClassObject.GetType()
                 .GetMethod("ConvertColors")
                 .GetParameters()[0]
                 .ParameterType
                 .GetProperty("Item")
                 .PropertyType;
dynamic colorList = Activator.CreateInstance(listType);
dynamic customColor = Activator.CreateInstance(colorType);
colorList.Add(customColor);

myClassObject.ConvertColors(colorList); //works!