C# 通过反射调用具有类参数的方法
我刚从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) { //
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!