Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

could support T : new() like C#? #1787

Closed
Silentdoer opened this issue Aug 7, 2021 · 2 comments
Closed

could support T : new() like C#? #1787

Silentdoer opened this issue Aug 7, 2021 · 2 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@Silentdoer
Copy link

such as C# code:

class ItemFactory<T> where T : new()
    {
        public T GetNewItem()
        {
            return new T();
        }
    }

it's very useful when we want return a value of T, such as:

class Foo<T> where T : new() {
  T test() {
    return T();
  }
}
@Silentdoer Silentdoer added the feature Proposed language feature that solves one or more problems label Aug 7, 2021
@ykmnkmi
Copy link

ykmnkmi commented Aug 7, 2021

where T: new() accept classes with a default constructor?

@Levi-Lesches
Copy link

Levi-Lesches commented Aug 8, 2021

First of all, you can do this today:

class Foo<T> {
  final T Function() constructor;
  Foo(this.constructor);
  T test() => constructor();
}

or

typedef Constructor<T> = T Function();
class Foo<T> {
  T test(Constructor<T> constructor) => constructor();
}

But to address your request, there has been discussion at #1612 of specifying types by listing the members you want ("structural typing" or "duck typing", similar to what Python uses). A common example is requesting an object with .length. The syntax hasn't been decided on yet -- or even if this should be allowed -- but it could look something like this:

abstract class HasLength {
  int get length;
}

/// Accepts any object with a `.length` property, even if they don't extend [HasLength].
///
/// That means [String], [Map], [List], [Set], etc. all work.
void printLength(HasLength obj) => print(obj.length);
// alternatively: 
void printLength(dynamic<HasLength> obj) => print(obj.length);

What you would want, then, is this:

abstract class Constructor{
  Constructor();
}

class Foo<T extends Constructor> {
  T test() => T();
}
// or 
class Foo<T extends dynamic<Constructor>> {
  T test() => T();
}

Perhaps using the .new syntax from #1564, you can shorten that to:

abstract class Constructor{ new(); }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants