我刚刚开始使用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方法创建适当的参数。 :(
答案 0 :(得分:0)
我不确定您是如何创建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());
答案 1 :(得分:0)
汤姆,
尝试传递您想要转换的颜色作为参考。
在下面的示例中,您作为参考传入的颜色(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...
};
答案 2 :(得分:0)
在一个不眠之夜后,我实际上想出了如何实现这一目标。这两个答案确实帮助我看到了导致我得到答案的可能性,但是我必须在不引用外部DLL或对其进行任何修改的情况下实现这一点,只需通过Reflection获取它的主要对象的实例,然后调用各种其中的方法(其中一些只需要DLL本身提供的类,如我的例子所示)。
我的解决方案是这样的(随意提供更好的选择):
使用方法参数:
获取List和CustomColor的类型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!