What is the difference between dynamic and Object in dart?
Asked Answered
H

8

89

They both seem like they can be used in identical cases. Is there a different representation or different subtleties in type checking, etc?

Hackery answered 7/7, 2015 at 0:10 Comment(0)
U
73

The section Type dynamic from the Dart Programming Language Specification, 3rd Edition states :

Type dynamic has methods for every possible identifier and arity, with every possible combination of named parameters. These methods all have dynamic as their return type, and their formal parameters all have type dynamic. Type dynamic has properties for every possible identifier. These properties all have type dynamic.

That means you will not get warnings by calling any method on a dynamic typed variable. That will not be the case with a variable typed as Object. For instance:

dynamic a;
Object b;

main() {
  a = "";
  b = "";
  printLengths();
}

printLengths() {
  // no warning
  print(a.length);

  // warning:
  // The getter 'length' is not defined for the class 'Object'
  print(b.length);
}

At runtime, I think, you shouldn't see any difference.

Uncouth answered 7/7, 2015 at 9:37 Comment(0)
S
117

Edited to update for null safety (use Object? instead of Object).

Another perspective on dynamic is that it's not really a type - it's a way to turn off type checking and tell the static type system "trust me, I know what I'm doing". Writing dynamic o; declares a variable that isn't typed - it's instead marked as "not type-checked".

When you write Object? o = something; you are telling the system that it can't assume anything about o except that it's an Object or null. You can call toString and hashCode because those methods are defined on Object and Null, but if you try to do o.foo() you will get a warning - it can't see that you can do that, and so it warns you that your code is probably wrong.

If you write dynamic o = something you are telling the system to not assume anything, and to not check anything. If you write o.foo() then it will not warn you. You've told it that "anything related to o is OK! Trust me, I know what I'm doing", and so it thinks o.foo() is OK.

With great power comes great responsibility - if you disable type-checking for a variable, it falls back on you to make sure you don't do anything wrong.

Scrutiny answered 8/7, 2015 at 14:35 Comment(0)
U
73

The section Type dynamic from the Dart Programming Language Specification, 3rd Edition states :

Type dynamic has methods for every possible identifier and arity, with every possible combination of named parameters. These methods all have dynamic as their return type, and their formal parameters all have type dynamic. Type dynamic has properties for every possible identifier. These properties all have type dynamic.

That means you will not get warnings by calling any method on a dynamic typed variable. That will not be the case with a variable typed as Object. For instance:

dynamic a;
Object b;

main() {
  a = "";
  b = "";
  printLengths();
}

printLengths() {
  // no warning
  print(a.length);

  // warning:
  // The getter 'length' is not defined for the class 'Object'
  print(b.length);
}

At runtime, I think, you shouldn't see any difference.

Uncouth answered 7/7, 2015 at 9:37 Comment(0)
S
17

dynamic is not a type, it just disables type checking. Object is the 'union' of all non-nullable types, type checking rules still apply.

Compare these two cases:

Case 1 (dynamic)

// a 'dynamic' variable can be assigned value of any type
dynamic a = 2;

// assign 'dynamic' value to any variable and code checker will not complain
int b = a;
// even when there is a bug
String c = a;

Case 2 (Object)

// It is OK to assign a 'int' value to an 'Object' variable, because 'int' is a subtype of 'Object'
Object a = 2;

// will get type error: "A value of type 'Object' can't be assigned to a variable of type 'int'"
int b = a;

// typecast is required when assign a 'Object' value to a variale of one of its subtypes.
int c = a as int;
Sessile answered 7/12, 2020 at 0:52 Comment(0)
I
14

To add to Alexandre's answer on the practical difference, there is also a semantic difference between the two, and using the right one will help to better communicate your intent to other programmers.

When you use Object you are saying that you know the type that you are working with and it is Object. For instance:

int getHashCode(Object obj) {
  return obj.hashCode;
}

Since hashCode is a property on Object we use Object as the parameter type to specify that the function can accept anything of type Object.

On the other hand, using dynamic means that the Dart system cannot properly express the type that you want to use:

void setEmail(dynamic email) {
  if (email is Email) {
    _email = email;
  } else if (email is String) {
    _email = new Email.fromString(email);
  }
}

Since Dart doesn't currently support union types there is no way to express the type Email | String so we are forced to use dynamic to accept all types and then only handle the cases where the type is one we are interested in.

Inoculum answered 7/7, 2015 at 20:4 Comment(2)
There is actually no difference between using Object and dynamic in the example you have given here.Scrutiny
There is no practical difference, and you can swap the two and the program will run the same. When I refer to "semantic difference", I mean how the code will be understood by other Dart programmers. I've slightly altered my answer to better reflect that.Inoculum
S
6

Object cannot access "properties" and "methods" defined in a class. However, with dynamic you can access class members.

Check this example:

class MyClass{
    myFunction() => print("This works");        
}

void main(){
   dynamic dyn = new MyClass();
   Object obj = new MyClass();
   dyn.myFunction(); // prints "This works" without any error
   obj.myFunction(); // Error: myFunction isn't defined for obj
}
Shack answered 7/5, 2021 at 12:19 Comment(1)
Yeah, it makes sense, with Object you are using an Object reference to access MyClass instance, and of course that reference is not aware of that instance's own methods. With dynamic, you access the actual MyClass reference, hoping that you will call an existing method.Martlet
A
4

In addition to the answer given by lrn, it is also worth noting, that for Dart Version 2.12 and higher with Null safety enabled, a variable declared as dynamic can be null, while a variable of type Object cannot be null.

Accused answered 10/10, 2021 at 13:52 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Forbid
A
2

also, I've noted that extension methods does not work correctly with dynamic but worked ok with Object.


// I used to have the extension on dynamic and had 
// problems that didn't occur when using the same extension on Object

extension UtilExtensions on Object {   

  bool get isStringNotEmpty => this is String && (this as String).isNotEmpty;
  String get asStringNotEmpty => isStringNotEmpty ? this as String : null;

  bool get isIntNotZero => this is int && (this as int) != 0;
  int get asIntNotZero => isIntNotZero ? this as int : null;

  Map<String, Object> get asPair {
    if (this != null && this is Map) {
      return (this as Map).cast<String, Object>();
    }

    return null;
  }

  Map<String, Object> get asFullPair {
    if (this != null && this is Map) {
      var ret = (this as Map).cast<String, Object>();

      for (var key in ret.keys) {
        var val = ret[key];

        if (val is Map) {
          ret[key] = val.asFullPair;
        }
      }

      return ret;
    }

    return null;
  }
}
Albata answered 27/3, 2020 at 15:16 Comment(0)
K
1

dynamic is a keyword to assign a value in a variable with no type checking. Object is the parent class of all classes in Dart and it can be used as a data type with type checking.

Kudos answered 31/1, 2023 at 5:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.