C#将类作为字符串传递,并从数组中强制转换它



我有一些嵌套类,如"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.
}

我一直在摆弄Reflections,Generics,但我仍然无法让它发挥作用。

谢谢。

您应该为此使用泛型:

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);
    }
}

我认为问题在于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 });  

不能将对象强制转换为只知道其字符串名称的类型。因此,您也不能以这种方式访问其字段。您可以选择访问以下类型的字段:

  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);

相关内容

  • 没有找到相关文章