How do you access multiple mixins via reflection in Dart? - dart

Here's the simplest example.
class MixA{
}
class MixB{
}
class Base{
}
class MyClass extends Base with MixA, MixB{
}
main(){
var m = new MyClass();
reflect(m).superclass.mixin; //This only gives MixB. Is there a way to get a list of all the mixins?
}
I can't find a way to just get a list of all the mixins that were applied to MyClass

Each mixin application creates a new subclass:
void main(){
final m = new MyClass();
final r = reflect(m);
print(r.type.superclass.mixin);
print(r.type.superclass.superclass.mixin);
}

Related

Can i pass the generic type in dart programatically from a variable?

Consider this code
final dynamic bar;
class Foo<T> {
const Foo(this.bla) : assert(T == A, T == B);
final T bla;
}
...
final Foo foo = Foo(bla); // Assert will trigerred because bla is dynamic even it is A type.
I don't know the bla type but i can assured its on a A type or B type.
I want to do something like this?
final Foo foo = Foo<bla.runtimeType>(bla);
You should write base class that encompasses class A and B. You should send class Foo that derives from this base class.
abstract class Base{
void printName();
}
class A extends Base{
A();
#override
printName(){
print("A class");
}
}
class B extends Base{
B();
#override
printName(){
print("b class");
}
}
class Foo {
Base bla;
Foo(this.bla);
}
void main(){
dynamic a=A();
Foo fooA = Foo(a);
fooA.bla.printName();
dynamic b=B();
Foo fooB = Foo(b as Base);
fooB.bla.printName();
}
You should be careful here Foo fooB = Foo(b as Base);. If this cast cannot be done, it will give an error.I suggest you use try catch block
look here for generic type check
because T==A (any className) in assert blog will not give correct result
for more information

Dart any differences between with or without abstract keyword?

Hi I just would like to know if there is any difference between giving abstract keyword or not like so.
// with
abstract class A {}
class B extends A {}
// without
class A {}
class B extends A {}
Should I give it?
With abstract you can omit implementations of methods and getters/setters
// with
abstract class A {
int foo();
String get bar;
set baz(String value);
}
var a = A(); // error about instantiating abstract class
class B extends A {
// error about missing implementations
}
var b = B(); // ok
// without
class A {
int foo(); // error about missing implementation
String get bar; // error about missing implementation
set baz(String value); // error about missing implementation
}
class B extends A {}

how to split dart class in flutter?

I did the following test, but it doesn't work:
//main.dart
class Test
{
static const a = 10;
final b = 20;
final c = a+1;
}
//part.dart
part of 'main.dart';
class Test
{
final d = a +1; //<---undefined name 'a'
}
I would like to split the class in flutter tutorial into multiple files. For example: _buildSuggestions in a separate file, _buildRow in a separate file, etc.
update:
my solution:
before:
//main.dart
class RandomWordsState extends State<RandomWords> {
{
final _var1;
final _var2;
#override
Widget build(BuildContext context) {
...
body: _buildList(),
);
Widget _buildList() { ... }
Widget _buildRow() { ... }
}
after:
//main.dart
import 'buildlist.dart';
class RandomWordsState extends State<RandomWords> {
{
final var1;
final var2;
#override
Widget build(BuildContext context) {
...
body: buildList(this),
);
}
//buildlist.dart
import 'main.dart';
Widget buildList(RandomWordsState obj) {
... obj.var1 ...
}
I am faced with same problem. My variant based on extensions:
page.dart
part 'section.dart';
class _PageState extends State<Page> {
build(BuildContext context) {
// ...
_buildSection(context);
// ...
}
}
section.dart
part of 'page.dart';
extension Section on _PageState {
_buildSection(BuildContext context) {
// ...
}
}
Dart doesn't support partial classes. part and part of are to split a library into multiple files, not a class.
Private (identifiers starting with _) in Dart is per library which is usually a *.dart file.
main.dart
part 'part.dart';
class Test {
/// When someone tries to create an instance of this class
/// Create an instance of _Test instead
factory Test() = _Test;
/// private constructor that can only be accessed within the same library
Test._();
static const a = 10;
final b = 20;
final c = a+1;
}
part.dart
part of 'main.dart';
class _Test extends Test {
/// private constructor can only be called from within the same library
/// Call the private constructor of the super class
_Test() : super._();
/// static members of other classes need to be prefixed with
/// the class name, even when it is the super class
final d = Test.a +1; //<---undefined name 'a'
}
A similar pattern is used in many code-generation scenarios in Dart like in
https://pub.dartlang.org/packages/built_value
https://pub.dartlang.org/packages/built_redux
https://pub.dartlang.org/packages/json_serializable
and many others.
I just extend it with extension keyword like Swift.
// class_a.dart
class ClassA {}
// class_a+feature_a.dart
import 'class_a.dart';
extension ClassA_FeatureA on ClassA {
String separatedFeatureA() {
// do your job here
}
}
Please ignore the coding conventions, it's just a sample.

Creating an instance of a generic type in DART

I was wondering if is possible to create an instance of a generic type in Dart. In other languages like Java you could work around this using reflection, but I'm not sure if this is possible in Dart.
I have this class:
class GenericController <T extends RequestHandler> {
void processRequest() {
T t = new T(); // ERROR
}
}
I tried mezonis approach with the Activator and it works. But it is an expensive approach as it uses mirrors, which requires you to use "mirrorsUsed" if you don't want to have a 2-4MB js file.
This morning I had the idea to use a generic typedef as generator and thus get rid of reflection:
You define a method type like this: (Add params if necessary)
typedef S ItemCreator<S>();
or even better:
typedef ItemCreator<S> = S Function();
Then in the class that needs to create the new instances:
class PagedListData<T>{
...
ItemCreator<T> creator;
PagedListData(ItemCreator<T> this.creator) {
}
void performMagic() {
T item = creator();
...
}
}
Then you can instantiate the PagedList like this:
PagedListData<UserListItem> users
= new PagedListData<UserListItem>(()=> new UserListItem());
You don't lose the advantage of using generic because at declaration time you need to provide the target class anyway, so defining the creator method doesn't hurt.
You can use similar code:
import "dart:mirrors";
void main() {
var controller = new GenericController<Foo>();
controller.processRequest();
}
class GenericController<T extends RequestHandler> {
void processRequest() {
//T t = new T();
T t = Activator.createInstance(T);
t.tellAboutHimself();
}
}
class Foo extends RequestHandler {
void tellAboutHimself() {
print("Hello, I am 'Foo'");
}
}
abstract class RequestHandler {
void tellAboutHimself();
}
class Activator {
static createInstance(Type type, [Symbol constructor, List
arguments, Map<Symbol, dynamic> namedArguments]) {
if (type == null) {
throw new ArgumentError("type: $type");
}
if (constructor == null) {
constructor = const Symbol("");
}
if (arguments == null) {
arguments = const [];
}
var typeMirror = reflectType(type);
if (typeMirror is ClassMirror) {
return typeMirror.newInstance(constructor, arguments,
namedArguments).reflectee;
} else {
throw new ArgumentError("Cannot create the instance of the type '$type'.");
}
}
}
I don't know if this is still useful to anyone. But I have found an easy workaround. In the function you want to initialize the type T, pass an extra argument of type T Function(). This function should return an instance of T. Now whenever you want to create object of T, call the function.
class foo<T> {
void foo(T Function() creator) {
final t = creator();
// use t
}
}
P.S. inspired by Patrick's answer
2022 answer
Just came across this problem and found out that although instantiating using T() is still not possible, you can get the constructor of an object easier with SomeClass.new in dart>=2.15.
So what you could do is:
class MyClass<T> {
final T Function() creator;
MyClass(this.creator);
T getGenericInstance() {
return creator();
}
}
and when using it:
final myClass = MyClass<SomeOtherClass>(SomeOtherClass.new)
Nothing different but looks cleaner imo.
Here's my work around for this sad limitation
class RequestHandler {
static final _constructors = {
RequestHandler: () => RequestHandler(),
RequestHandler2: () => RequestHandler2(),
};
static RequestHandler create(Type type) {
return _constructors[type]();
}
}
class RequestHandler2 extends RequestHandler {}
class GenericController<T extends RequestHandler> {
void processRequest() {
//T t = new T(); // ERROR
T t = RequestHandler.create(T);
}
}
test() {
final controller = GenericController<RequestHandler2>();
controller.processRequest();
}
Sorry but as far as I know, a type parameter cannot be used to name a constructor in an instance creation expression in Dart.
Working with FLutter
typedef S ItemCreator<S>();
mixin SharedExtension<T> {
T getSPData(ItemCreator<T> creator) async {
return creator();
}
}
Abc a = sharedObj.getSPData(()=> Abc());
P.S. inspired by Patrick
simple like that.
import 'dart:mirrors';
void main(List<String> args) {
final a = A<B>();
final b1 = a.getInstance();
final b2 = a.getInstance();
print('${b1.value}|${b1.text}|${b1.hashCode}');
print('${b2.value}|${b2.text}|${b2.hashCode}');
}
class A<T extends B> {
static int count = 0;
T getInstance() {
return reflectClass(T).newInstance(
Symbol(''),
['Text ${++count}'],
{Symbol('value'): count},
).reflectee;
}
}
class B {
final int value;
final String text;
B(this.text, {required this.value});
}
Inspired by Patrick's answer, this is the factory I ended up with.
class ServiceFactory<T> {
static final Map<Type, dynamic> _cache = <String, dynamic>{};
static T getInstance<T>(T Function() creator) {
String typeName = T.toString();
return _cache.putIfAbsent(typeName, () => creator());
}
}
Then I would use it like this.
final authClient = ServiceFactory.getInstance<AuthenticationClient>(() => AuthenticationClient());
Warning: Erik made a very good point in the comment below that the same type name can exist in multiple packages and that will cause issues. As much as I dislike to force the user to pass in a string key (that way it's the consumer's responsibility to ensuring the uniqueness of the type name), that might be the only way.

Is this possible in Dart to define similar declaration `GroupByIterator<TSource, Grouping<TKey, TElement>>`

I cannot declare class in this manner. May be I am wrong. Is this possible in other way?
class GroupByIterator<TSource, Grouping<TKey, TElement>> {
}
class Grouping<TKey, TElement> {
}
I got a dozen compiler errors on this declaration.
Please, help me define similar declaration.
P.S.
I know the following way, but I want to know that it can be made easier?..
void main() {
var it1 = new GroupByIterator<List, Grouping<int, String>, int, String>();
}
class GroupByIterator<TSource, TResult extends Grouping<TKey, TElement>, TKey, TElement> {
GroupByIterator() {
print('GroupByIterator');
}
}
class Grouping<TKey, TElement> {
}
I want simialr to this.
var it1 = new GroupByIterator<List, Grouping<int, String>>();
class GroupByIterator<TSource, TResult, TKey, TElement, T extends Grouping<TKey, TElement>> implements Iterator<TResult> {
GroupByIterator() {
print('GroupByIterator');
}
}
It seems that you must list all Type parameters in the 'top' level to use it in the following 'lower' levels.

Resources