我刚刚开始使用c#反射,我遇到了调用以内部类作为参数的方法的问题:
样本类:public class MyClass
{
public class CustomColor
{
public int h;
public int s;
public int v;
}
public string[] ConvertColors(List<CustomColor> colors)
{
//...
}
}
我用来调用这个类中其他方法的代码:
FieldInfo info = cInstanceContainerObject.GetType().GetField("_myClass", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
dynamic myClassObject = info.GetValue(cInstanceContainerObject);
允许我这样做:
myClassObject.SomeSampleMethod(int sampleParam);
然而,我一直在弄清楚如何为上面的ConvertColors方法创建适当的参数。(
我不知道你是如何创建你的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());
Tom,
尝试传递要转换的颜色作为引用。
在下面的例子中,作为引用传入的颜色(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;
}
}
}
解释:
'enum'允许你为你的方法创建一个自定义参数:
public enum Convert { H, S, V, HS, HV, SV, HSV };
'switch'语句允许你处理这些参数:
switch (type)
{
case Convert.H:
// Do something
return;
case Convert.S:
// Do something
return;
case Convert.V:
// Do something
return;
创建一个您想要做的更改的实例作为一个新的CustomColor,并传递一个对CustomColors列表的引用,您的自定义参数,以及一个对更改的引用作为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.
}
如果您希望获得后面的字符串:
string[] hsvStrings =
{
color1.h.ToString(),
color1.s.ToString(),
color1.v.ToString(),
// Continue...
};
经过一个不眠之夜,我终于想出了如何实现这一目标。两个答案都帮助我看到了导致我得到答案的可能性,但是我必须在不引用外部DLL或对其进行任何修改的情况下实现这一点,只是通过反射获得它的主对象的实例,然后调用其中的各种方法(其中一些需要的类仅由DLL本身提供,正如您可以在我的示例中看到的)。
我的解决方案是这样的(请随意提供更好的替代方案):
通过使用方法参数
获取List和CustomColor各自的Type:Type listType = myClassObject.GetType()
.GetMethod("ConvertColors")
.GetParameters()[0]
.ParameterType;
Type colorType = myClassObject.GetType()
.GetMethod("ConvertColors")
.GetParameters()[0]
.ParameterType
.GetProperty("Item")
.PropertyType;
然后使用Activator:
创建整个列表和单个CustomColors的单独实例dynamic colorList = Activator.CreateInstance(listType);
dynamic customColor = Activator.CreateInstance(colorType);
colorList.Add(customColor);
myClassObject.ConvertColors(colorList); //works!