Content deleted Content added
(19 intermediate revisions by the same user not shown) | |||
Line 77:
using std::views::filter;
class Foo {
private:
// ...
public:
void printHello() const noexcept {
std::println("Hello, world!");
}
};
[[nodiscard]]
consteval bool isNonstaticMethod(info mem) noexcept {
return is_class_member(mem)
&& !is_static_member(mem)
Line 83 ⟶ 93:
}
[[nodiscard]]
consteval info findMethod(info ty, const char* name) {
constexpr auto ctx = std::meta::access_context::current();
Line 94 ⟶ 105:
template <info Ty, auto Name>
constexpr auto createInvokerImpl = []() -> auto {
using Type = [: Ty :];
static constexpr info M = findMethod(Ty, Name);
static_assert(parameters_of(M).size() == 0 && return_type_of(M) == ^^void);
return [](Type& instance) -> void { instance.[: M :](); };
}();
[[nodiscard]]
consteval info createInvoker(info ty, string_view name) {
return substitute(^^createInvokerImpl, {
Line 125 ⟶ 137:
<syntaxhighlight lang="c#">
using System;
using System.Reflection;
class Foo {
// ...
public void PrintHello() {
Console.WriteLine("Hello, world!");
}
}
public class InvokeFooExample {
static void Main(string[] args) {
// Without reflection
Foo foo = new Foo();
foo.PrintHello();
// With reflection
Object foo = Activator.CreateInstance("complete.classpath.and.Foo");
MethodInfo method = foo.GetType().GetMethod("PrintHello");
method.Invoke(foo, null);
}
}
</syntaxhighlight>
Line 209 ⟶ 235:
import java.lang.reflect.Method;
class Foo {
// ...
public void printHello() {
System.out.println("Hello, world!");
}
}
public class InvokeFooExample {
public static void main(String[] args) {
// Without reflection
Foo foo = new Foo();
foo.printHello();
// With reflection
Foo foo = Foo.class.getDeclaredConstructor().newInstance();
Method m = foo.getClass().getDeclaredMethod("printHello", new Class<?>[0]);
m.invoke(foo);
} catch (ReflectiveOperationException e) {
System.err.printf("An error occurred: %s%n", e.getMessage());
}
}
}
</syntaxhighlight>
Line 287 ⟶ 326:
// Sending "hello" to a Foo instance without reflection.
Foo
[obj hello];
Line 340 ⟶ 379:
<syntaxhighlight lang="python">
from typing import Any
class Foo:
# ...
def print_hello() -> None:
print("Hello, world!")
if __name__ == "__main__":
# Without reflection
obj: Foo = Foo()
obj.print_hello()
# With reflection
obj: Foo = globals()["Foo"]()
_: Any = getattr(obj, "print_hello")()
# With eval
eval("Foo().print_hello()")
</syntaxhighlight>
Line 381 ⟶ 428:
# With eval
eval "Foo.new.hello"
</syntaxhighlight>
===Rust===
[[Rust (programming language)|Rust]] does not have compile-time reflection in the standard library, but it is possible using some third-party libraries such as "[https://docs.rs/bevy_reflect/latest/bevy_reflect/ {{mono|bevy_reflect}}]".
<syntaxhighlight lang="rust">
use std::any::TypeId;
use bevy_reflect::prelude::*;
use bevy_reflect::{
FunctionRegistry,
GetTypeRegistration,
Reflect,
ReflectFunction,
ReflectFunctionRegistry,
ReflectMut,
ReflectRef,
TypeRegistry
};
#[derive(Reflect)]
#[reflect(DoFoo)]
struct Foo {
// ...
}
impl Foo {
fn new() -> Self {
Foo {}
}
fn print_hello(&self) {
println!("Hello, world!");
}
}
#[reflect_trait]
trait DoFoo {
fn print_hello(&self);
}
impl DoFoo for Foo {
fn print_hello(&self) {
self.print_hello();
}
}
fn main() {
// Without reflection
let foo: Foo = Foo::new();
foo.print_hello();
// With reflection
let mut registry: TypeRegistry = TypeRegistry::default();
registry.register::<Foo>();
registry.register_type_data::<Foo, ReflectFunctionRegistry>();
registry.register_type_data::<Foo, ReflectDoFoo>();
let foo: Foo = Foo;
let reflect_foo: Box<dyn Reflect> = Box::new(foo);
// Version 1: call hello by trait
let trait_registration: &ReflectDoFoo = registry
.get_type_data::<ReflectDoFoo>(TypeId::of::<Foo>())
.expect("ReflectDoFoo not found for Foo");
let trait_object: &dyn DoFoo = trait_registration
.get(&*reflect_foo)
.expect("Failed to get DoFoo trait object");
trait_object.print_hello();
// Version 2: call hello by function name
let func_registry: &FunctionRegistry = registry
.get_type_data::<FunctionRegistry>(TypeId::of::<Foo>())
.expect("FunctionRegistry not found for Foo");
if let Some(dyn_func) = func_registry.get("print_hello") {
let result: Option<Box<dyn Reflect>> = dyn_func
.call(&*reflect_foo, Vec::<Box<dyn Reflect>>::new())
.ok();
if result.is_none() {
println!("Function called, no result returned (as expected for void return)");
}
} else {
println!("No function named hello found in FunctionRegistry");
}
}
</syntaxhighlight>
|