You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dart中实现基于条件遍历类列表并赋值变量(Python等效)

How to Iterate Over a List of Classes and Assign Instances in Dart

Great question! Let's break this down into two parts and walk through how to implement this in Dart, since the approach has some key differences from Python.

Part 1: Basic Iteration Over a List of Classes

In Dart, you can store classes directly in a list (they're represented as Type objects), but creating instances from these types requires a bit of care. Here are two common approaches:

Instead of storing the class types themselves, store functions that return instances of each class. This avoids reflection and keeps your code type-safe:

class A {}
class B {}
class C {}

void main() {
  // List of constructor functions that return class instances
  final classConstructors = [() => A(), () => B(), () => C()];
  final instances = <Object>[];

  for (final constructor in classConstructors) {
    final instance = constructor();
    instances.add(instance);
  }

  print(instances); // Output: [Instance of 'A', Instance of 'B', Instance of 'C']
}

Approach 2: Conditional Checks (Simple, Less Scalable)

If you only have a small number of classes, you can check the type directly and instantiate accordingly:

class A {}
class B {}
class C {}

void main() {
  final classList = [A, B, C];
  final instances = <Object>[];

  for (final cls in classList) {
    Object? instance;
    if (cls == A) instance = A();
    else if (cls == B) instance = B();
    else if (cls == C) instance = C();
    
    if (instance != null) instances.add(instance);
  }

  print(instances); // Output: [Instance of 'A', Instance of 'B', Instance of 'C']
}

Part 2: Conditional Iteration (Matching Your Example Logic)

Your sample code hits a roadblock in Dart: you can't directly access static members like items from a Type object. Let's fix this with two practical solutions:

Solution 1: Encapsulate Class Metadata (Best for Production)

Create a helper class to wrap each target class's static items list and its constructor. This keeps your code type-safe, fast, and avoids reflection:

class A {
  static final List<String> items = ['item1', 'item2', 'item3'];
}

class B {
  static final List<String> items = ['item1', 'item2', 'item3'];
}

class C {
  static final List<String> items = ['item1', 'item2', 'item3'];
}

// Helper class to hold static data and constructor for each class
class ClassMetadata<T> {
  final List<String> items;
  final T Function() constructor;

  ClassMetadata(this.items, this.constructor);
}

class SelectSuitableClass {
  dynamic selectedClass;
  final String item;
  final List<ClassMetadata> _classMetadata = [
    ClassMetadata(A.items, () => A()),
    ClassMetadata(B.items, () => B()),
    ClassMetadata(C.items, () => C()),
  ];

  SelectSuitableClass(this.item) {
    bool foundMatch = false;
    for (final meta in _classMetadata) {
      for (final i in meta.items) {
        if (item.contains(i)) {
          selectedClass = meta.constructor();
          foundMatch = true;
          break;
        }
      }
      if (foundMatch) break;
    }

    if (!foundMatch) {
      throw Exception('No suitable class found for item: "$item"');
    }
  }
}

void main() {
  try {
    final selector = SelectSuitableClass('item2');
    print(selector.selectedClass); // Output: Instance of 'A' (first matching class)
  } catch (e) {
    print(e);
  }
}

Solution 2: Use Reflection (dart:mirrors)

If you need to access static members directly without encapsulation, you can use Dart's reflection library. Note: Reflection is not recommended for production (especially in Flutter) as it increases app size and can be slower.

import 'dart:mirrors';

class A {
  static final List<String> items = ['item1', 'item2', 'item3'];
}

class B {
  static final List<String> items = ['item1', 'item2', 'item3'];
}

class C {
  static final List<String> items = ['item1', 'item2', 'item3'];
}

class SelectSuitableClass {
  dynamic selectedClass;
  final String item;
  final List<Type> _myClasses = [A, B, C];

  SelectSuitableClass(this.item) {
    bool foundMatch = false;
    for (final cls in _myClasses) {
      // Get the class mirror to access static members
      final classMirror = reflectClass(cls);
      final items = classMirror.getField(Symbol('items')).reflectee as List<String>;
      
      for (final i in items) {
        if (item.contains(i)) {
          // Create an instance using the default constructor
          selectedClass = classMirror.newInstance(Symbol(''), []).reflectee;
          foundMatch = true;
          break;
        }
      }
      if (foundMatch) break;
    }

    if (!foundMatch) {
      throw Exception('No suitable class found for item: "$item"');
    }
  }
}

void main() {
  try {
    final selector = SelectSuitableClass('item3');
    print(selector.selectedClass); // Output: Instance of 'A'
  } catch (e) {
    print(e);
  }
}

Key Takeaways

  • Use encapsulation (Solution 1) for most cases—it's type-safe, performant, and works everywhere.
  • Avoid reflection unless you have a specific, advanced use case that can't be solved with encapsulation.

内容的提问来源于stack exchange,提问作者Salman Aljabri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:20:19