Давайте перепишем ваш код следующим образом:
x = 1
y = [x]
z = y * 4
myList = [z] * 3
После этого запустите следующий код, чтобы сделать все более понятным. Что делает код, в основном печатает id
s полученных объектов, которые
Вернуть «идентификатор» объекта
blockquote >и поможет нам идентифицировать их и проанализировать, что происходит:
print("myList:") for i, subList in enumerate(myList): print("\t[{}]: {}".format(i, id(subList))) for j, elem in enumerate(subList): print("\t\t[{}]: {}".format(j, id(elem)))
И вы получите следующий результат:
x: 1 y: [1] z: [1, 1, 1, 1] myList: [0]: 4300763792 [0]: 4298171528 [1]: 4298171528 [2]: 4298171528 [3]: 4298171528 [1]: 4300763792 [0]: 4298171528 [1]: 4298171528 [2]: 4298171528 [3]: 4298171528 [2]: 4300763792 [0]: 4298171528 [1]: 4298171528 [2]: 4298171528 [3]: 4298171528
Итак, теперь давайте шаг за шагом. У вас есть
x
, который является1
, и единственным списком элементовy
, содержащимx
. Ваш первый шаг -y * 4
, который даст вам новый списокz
, который в основном[x, x, x, x]
, т. Е. Создает новый список, который будет содержать 4 элемента, которые являются ссылками на исходный объектx
. Чистый шаг очень похож. В основном вы делаетеz * 3
, который является[[x, x, x, x]] * 3
и возвращает[[x, x, x, x], [x, x, x, x], [x, x, x, x]]
по той же причине, что и для первого шага.
использовать отражение, чтобы проверить, есть ли у него метод «CustomType MyMethod (byte [] a, int b)» и называть его или выдавать исключение иначе
blockquote>Ваш текущий код не выполняет это требование. Но вы можете довольно легко с чем-то вроде этого:
var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(byte[]), typeof(int) }); if (methodInfo == null) // the method doesn't exist { // throw some exception } var o = Activator.CreateInstance(t); var result = methodInfo.Invoke(o, params);
Достаточно ли это, или есть лучшие / более быстрые / короткие способы?
blockquote>As насколько я заинтересован, это лучший способ, и на самом деле нет ничего более быстрого для каждого из них.
Что относительно конструкторов, учитывая, что эти методы не являются статическими, можно ли их просто игнорировать?
blockquote>Вам все равно придется создать экземпляр
t
, как показано в моем примере. Это будет использовать конструктор по умолчанию без аргументов. Если вам нужно передать аргументы, вы можете увидеть документацию MSDN и изменить его как таковой.
Вы можете использовать динамический тип, который будет разрешен во время выполнения.
Type type = Type.GetType(className, true);
dynamic instance = Activator.CreateInstance(type);
var response = instance.YourMethod();
type
является статическим классом?
– Ozzah
19 February 2015 в 04:23
Поскольку это, кажется, популярный вопрос, вот полный пример исходного кода о том, как это сделать.
Предположим, что у нас есть сборка образцов, MyAssembly.dll , с класс MyClass . Мы хотим динамически загрузить его и вызвать его методы. Код MyAssembly :
namespace MyAssembly
{
public class MyClass
{
public int X { get; set; }
public int Y { get; set; }
public MyClass(int initialX, int initialY)
{
X = initialX;
Y = initialY;
}
public int MyMethod(int count, string text)
{
Console.WriteLine("This is a normal method.");
Console.WriteLine("Count: {0}", count);
Console.WriteLine("Text: {0}", text);
return this.X + this.Y;
}
public static void StaticMethod(int count, float radius)
{
Console.WriteLine("This is a static method call.");
Console.WriteLine("Count: {0}", count);
Console.WriteLine("Radius: {0}", radius);
}
}
}
Сначала мы хотели бы создать экземпляр класса с помощью конструктора MyClass(int initialX, int initialY)
, а затем вызвать метод public int MyMethod(int count, string text)
. Вот как вы это делаете из другого проекта (например, консольного приложения):
static void Main(string[] args)
{
//
// 1. Load assembly "MyAssembly.dll" from file path. Specify that we will be using class MyAssembly.MyClass
//
Assembly asm = Assembly.LoadFrom(@"C:\Path\MyAssembly.dll");
Type t = asm.GetType("MyAssembly.MyClass");
//
// 2. We will be invoking a method: 'public int MyMethod(int count, string text)'
//
var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(int), typeof(string) });
if (methodInfo == null)
{
// never throw generic Exception - replace this with some other exception type
throw new Exception("No such method exists.");
}
//
// 3. Define parameters for class constructor 'MyClass(int initialX, int initialY)'
//
object[] constructorParameters = new object[2];
constructorParameters[0] = 999; // First parameter.
constructorParameters[1] = 2; // Second parameter.
//
// 4. Create instance of MyClass.
//
var o = Activator.CreateInstance(t, constructorParameters);
//
// 5. Specify parameters for the method we will be invoking: 'int MyMethod(int count, string text)'
//
object[] parameters = new object[2];
parameters[0] = 124; // 'count' parameter
parameters[1] = "Some text."; // 'text' parameter
//
// 6. Invoke method 'int MyMethod(int count, string text)'
//
var r = methodInfo.Invoke(o, parameters);
Console.WriteLine(r);
}
Вызов статического метода public static void StaticMethod(int count, float radius)
выглядит так:
var methodInfoStatic = t.GetMethod("StaticMethod");
if (methodInfoStatic == null)
{
// never throw generic Exception - replace this with some other exception type
throw new Exception("No such static method exists.");
}
// Specify parameters for static method: 'public static void MyMethod(int count, float radius)'
object[] staticParameters = new object[2];
staticParameters[0] = 10;
staticParameters[1] = 3.14159f;
// Invoke static method
methodInfoStatic.Invoke(o, staticParameters);
o
? methodInfoStatic.Invoke(o, staticParameters);
– theonlygusti
29 October 2016 в 15:28
o
такой же, как в приведенном выше примере, но поскольку это статический метод, если я не ошибаюсь, вы можете просто передать null
вместо o
.
– w128
29 October 2016 в 17:33