2

我很少有嵌套类,例如“BlueprintsManager.WorkingStandardBlueprint”,以及具有它们实例的 ArrayList。我想将它们作为参数传递给方法,例如:

private void ShowBlueprints(string class_str, ArrayList class_array)
{
    // class_str would be passed as "BlueprintsManager.WorkingStandardBlueprint"
    // how here I can access class_str as a class and cast class_array to it, to access some variables.
    // for example, I need to access some BlueprintsManager.WorkingStandardBlueprint public variables.
}

我在搞乱反射,泛型,但我仍然无法让它工作。

谢谢你。

4

3 回答 3

1

您应该为此使用泛型:

private void ShowBlueprints<T>(List<T> class_array)
{
    for (BlueprintsManager.WorkingStandardBlueprint item in class_array)
    {
        if(typeof T is BlueprintsManager.WorkingStandardBlueprint)
        {
            Console.WriteLine(((BlueprintsManager.WorkingStandardBlueprint)item).whateverpropertyyouhavedefined);
        }
    }
}

现在您可以像这样调用该方法:

ShowBluePrints<BlueprintsManager.WorkingStandardBlueprint>(myblueprints);

编辑在评论中,OP 说所有属性都是相同的。该解决方案将起作用:

class BaseClass
{
    string Name {get; set;}
    int id {get; set;}
}

class BlueprintsManager
{
    class WorkingStandardBlueprint : BaseClass
    {

    }
}

private void ShowBlueprints<T>(List<T> class_array) where T : BaseClass
{
    for (T item in class_array)
    {       
        Console.WriteLine(item.Name);
    }
}
于 2013-04-20T23:51:49.990 回答
1

我认为问题why不仅仅是如何。我没有看到很多这样的结构。

如果满足您的需要,您应该使用泛型。

如果你真的需要construct types dynamically从一个任意的项目列表中

1)制作一个通用方法(就像已经建议的那样)

interface IBlueprint
{
    int ID {get;set;}
    int Name {get;set;}
}
class MyClass 
{
    private void ShowBlueprints<T>(IEnumerableT> values) where T : IBlueprint 
    {
        // access properties of IBlueprint
    }
    // I presume you 'know something' about your 'T'-s, have an interface -
    // ...if you don't you should if possible
}

2)然后这样称呼它(我从记忆中输入,但它应该是正确的)

MyClass myclass = new MyClass();
var values = // list of your blueprints
// if you don't have any in the list handle it and bail out
MethodInfo methodInfo = typeof(MyClass).GetMethod("ShowBlueprints");
MethodInfo methodInfoGeneric = 
    methodInfo.MakeGenericMethod(new[] { values.First().GetType() });
// or get your blueprint type from string if needed
methodInfoGeneric.Invoke(myclass, new object[] { values });  
于 2013-04-20T23:59:17.013 回答
0

您不能将对象转换为仅通过其字符串名称知道的类型。因此,您也无法以这种方式访问​​其字段。您有一些选项可以访问类型的字段:

  1. 您知道确切的类型(或其任何基本类型或接口),因此您可以直接强制转换:

    object first = class_array[0];
    var blueprint = (BlueprintsManager.WorkingStandardBlueprint)first;
    blueprint.MyProperty = 10;
    
  2. 您不知道确切的类型,但您非常确定它有一个具有特定名称的公共属性/字段。请注意dynamic此处的关键字,适用于 C# 4 及更高版本。

    dynamic blueprint = class_array[0];
    blueprint.MyProperty = 10;
    
  3. 您不知道确切的类型,但您会得到一个带有类型名称的字符串。而且您不知道确切的属性/字段,但您会得到一个带有属性名称的字符串。然后你可以使用反射:

    string typeName = "BlueprintsManager.WorkingStandardBlueprint";
    string propertyName = "MyProperty";
    
    var type = Assembly.GetExecutingAssembly().GetType(typeName);
    var property = type.GetProperty(propertyName);
    
    object first = class_array[0];
    // Getter:
    int result = (int)property.GetMethod.Invoke(first, null);
    // Setter
    property.SetMethod.Invoke(first, new object[] { 10 });
    

顺便说一句,你不应该使用ArrayList. 当泛型还不存在时,它是一个非常古老的类。今天你应该使用List<T>. 例如,当您知道所有实现具有您要使用的属性T的接口时:IBlueprint

private void ShowBlueprints<T>(string classStr, List<T> classArray)
    where T : IBlueprint
{
    T blueprint = classArray[0];
    blueprint.MyProperty = 10;
}

或者,如果您确实有任何类型的对象列表:

private void ShowBlueprints(string classStr, List<object> classArray);
于 2013-04-21T00:05:39.563 回答