cast with as

198 views
Skip to first unread message

Tom

unread,
Sep 8, 2012, 11:55:56 AM9/8/12
to mi...@dartlang.org
Here is the simple example to use as to cast, however, it seems that the child behave as the child after casting. Is it a bug? How can I to make child to behave like parent?

Thanks.

class ClassA {
 
  void outPut(){
    print ("print from ClassA");
  }
 
}

class Child extends ClassA
{
 // @override
  void outPut(){
   
    print("output from child!");
  }
 
}


void main() { 
  var c=new Child();
  var a=c as ClassA;
  a.outPut(); 
}

Tom

unread,
Sep 8, 2012, 12:05:59 PM9/8/12
to mi...@dartlang.org
Furthe more it still runs like a child even though the Editor complains about "ClassA has no such method" after I comment out method in parent.

What does the "AS" mean in dart? the behaviour seems different from C#.

Thanks

class ClassA {
 
//  void outPut(){
//    print ("print from ClassA");
//  }

Lasse R.H. Nielsen

unread,
Sep 8, 2012, 1:09:04 PM9/8/12
to mi...@dartlang.org
On Sat, Sep 8, 2012 at 6:05 PM, Tom <tomto...@gmail.com> wrote:
What does the "AS" mean in dart? the behaviour seems different from C#.

The 'as' cast operation in Dart for
  expr as Type
is equivalent to calling 
  new Cast<T>.cast(expr)
where Cast is defined as:

class Cast<T> {
   T cast(var value) {
     if (value != null && value is! T) throw new CastError();
     return value;
   }
}

That is:

The static type of the expression is Type. This affects static warnings.

At runtime it evaluates expr to a value, then tests if the result is null or has the type Type, and throws a CastError if it is neither. 

/L
-- 
Lasse R.H. Nielsen / l...@chromium.org
'Faith without judgement merely degrades the spirit divine'

Dirk Detering

unread,
Sep 9, 2012, 4:46:00 AM9/9/12
to mi...@dartlang.org

Am 08.09.2012 17:56 schrieb "Tom" <tomto...@gmail.com>:
>
> Here is the simple example to use as to cast, however, it seems that the child behave as the child after casting. Is it a bug? How can I to make child to behave like parent?
>

I must say, I don't know C#, so I'm wondering about the question a bit.

Just to tell my intuitive model here:

void main() { 
  var c=new Child(); 

  // the object ref'ed by c IS a child

  var a=c as ClassA;
  // the cast does not change fact that the ref'd object is a child
  // only the type of the reference may change.

  a.outPut(); 
  // the method is called on a reference 'a',
  // the ref'ed object is a Child.
}

A cast tells the typechecker something it doesn't know, but the developer does: That the given object, although referenced as type A can safely be used as type B.
(So I do not see the sense in an up-cast, like here, anyway. A downcast or a cast from dynamic to specific makes more sense).
A cast does not change what an object really IS.
So there is no reason why outPut() should work differently, when called on 'a' or 'c'. The concrete behaviour is defined by the object, and thus by the class that has been used to construct it (it would btw really confuse me if C# is different here, because that would break the concept of 'override').

Considering all that, I have not found any reason for warnings or runtime errors or different behaviour.

When you now drop the method from ClassA, it results in a warning because by the cast you documented that you want to TREAT the object AS a ClassA, but you call a method ClassA doesn't define. Nevertheless, the object IS a Child and indeed contains the method, which therefore can be called.
That the method call now only is a warning and not an error is due to Dart's philosophy of optional typing. The code's behaviour doesn't change by putting in types or leaving them away. You used the dynamic nature yourself by typing the variable dynamic with 'var'. Now leave the cast away too and nothing changes.

HTH
Det

Matthew Butler

unread,
Sep 9, 2012, 11:17:04 AM9/9/12
to mi...@dartlang.org
Something else very important to realize, regardless of casting, both variables a and c point to the same object in memory. We may be telling the vm to treat it as though it satisfies the parent class, but that object was created as a child. We are not creating a copy of the object as the parent class, it is still the original child object in memory.

Matt

Tom

unread,
Sep 9, 2012, 8:51:29 PM9/9/12
to mi...@dartlang.org
Here is one link about how does C# Polymorphism, Up-casting and Down-casting http://www.c-sharpcorner.com/UploadFile/pcurnow/polymorphcasting06222007131659PM/polymorphcasting.aspx
In C# there is a way to put new before the method, and after the cast, the child will behave like child and parent behave like parent. Does the Dart has the the same feature?

 
On Saturday, September 8, 2012 8:55:56 AM UTC-7, Tom wrote:

Dirk Detering

unread,
Sep 10, 2012, 12:44:27 AM9/10/12
to mi...@dartlang.org

Ah, thanks for that article, didn't know the C# way.
Just to learn more:
- I currently can't imagine any use case for that. Can you pls give one?
- I consider the mixed behaviour of one concrete object confusing. How often is it used, and how bug ridden is it in practice?

KR
Det

--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 

Jordan Miner

unread,
Sep 10, 2012, 1:32:22 AM9/10/12
to mi...@dartlang.org
C# and Dart (and Java) behave the same way with polymorphism (assuming
your C# methods are virtual). Casting doesn't change how an object
behaves. That's the point of polymorphism. A child will always behave
like a child even if it is cast to a parent. And you can't cast a
parent to a child unless it is actually a child. Both times Draw() is
called here, they do the same thing:

Shape s = new Circle(50, 10);
s.Draw(); // calls the Circle.Draw() method
Circle c = (Circle)s;
c.Draw(); // calls the Circle.Draw() method

Your example with the ClassA and Child classes should print "output
from child!" in both Dart and C#. (Again, assuming your methods are
virtual. If they aren't virtual, you aren't using polymorphism.)

Jordan

Jordan Miner

unread,
Sep 10, 2012, 2:32:30 AM9/10/12
to mi...@dartlang.org
Rereading, I noticed that I was focusing on your earlier email and not
your last one. I guess you are asking if Dart has non-virtual methods.
Dart does not.
http://en.wikipedia.org/wiki/Virtual_function
http://msdn.microsoft.com/en-us/library/aa645767.aspx
All methods in Dart are virtual. I think this is great. I really like
C#, but I'd say it is a mistake of C# to have non-virtual methods. The
Java and D way of having virtual by default and having final methods
to prevent overriding is fine. But without virtual methods, you don't
have polymorphism. The only reason I know of to have non-virtual
methods is performance.

Jordan

Bob Nystrom

unread,
Sep 10, 2012, 3:48:35 PM9/10/12
to mi...@dartlang.org
On Sun, Sep 9, 2012 at 9:44 PM, Dirk Detering <mail...@googlemail.com> wrote:

Ah, thanks for that article, didn't know the C# way.
Just to learn more:
- I currently can't imagine any use case for that. Can you pls give one?

I think, like explicit interface implementation, it comes into play occasionally when you find yourself needing to support multiple operations from different sources whose names happen to collide. For example, lets say you:

1. Make some class Foo.
2. Make some subclass Bar.
3. Add a method DoBlah() to Bar.
4. Release it into the wild.
5. Later, the author of Foo decides to add a DoBlah() method to it. It's not related to the one you already have in Bar.

The "new" modifier in C# lets you handle that situation. You mark the DoBlah() in Bar as new and it will be treated as a distinct method.

- I consider the mixed behaviour of one concrete object confusing. How often is it used, and how bug ridden is it in practice?

It's not used that often, and I think when you do use it, there's usually a strong enough motivation reason that you know what you're getting into. Ditto explicit interface implementation: you don't usually care about it, but when you do, you really do.

- bob

Bob Nystrom

unread,
Sep 10, 2012, 3:54:32 PM9/10/12
to mi...@dartlang.org
On Sat, Sep 8, 2012 at 9:05 AM, Tom <tomto...@gmail.com> wrote:
Furthe more it still runs like a child even though the Editor complains about "ClassA has no such method" after I comment out method in parent.

What does the "AS" mean in dart? the behaviour seems different from C#.

It is different from C# because Dart doesn't not have any static dispatch for instance methods. Instance method calls are always dynamically dispatched (i.e. all methods are virtual in Dart).

In C#, the static type of a variable (not the type of the actual object stored in the variable) can affect which method is called. In Dart that isn't the case. Its optional type system means type annotations never have an effect on runtime behavior.

For example:

class Base
{
  void Method() { System.Console.WriteLine("In Base"); }
}

class Derived : Base
{
  void Method() { System.Console.WriteLine("In Derived"); }
}

Main()
{
  Base obj1 = new Derived();
  obj1.Method();

  Derived obj2 = new Derived();
  obj2.Method();
}

This C# program will print "In Base" then "In Derived". (It will also have a shadowing warning.) This is because Method() is non-virtual so calls to it are dispatched statically, based on the declared type of the variable.

The same program in Dart:

class Base {
  void method() => print("In Base");
}

class Derived : Base {
  void method() => print("In Derived");
}

main() {
  Base obj1 = new Derived();
  obj1.method();

  Derived obj2 = new Derived();
  obj2.method();
}

Will print "In Derived" twice.

If you have overridden a method in Dart, there's no way to get to the base class method unless the overridden method itself calls super to delegate to it.

Cheers,

- bob

Christopher Wright

unread,
Sep 10, 2012, 4:25:28 PM9/10/12
to General Dart Discussion
To be pedantic, that C# program wouldn't compile. Make the methods public and slap a 'new' on the method in Derived, and it would have that behavior.

C# diverges from Java by allowing this sort of static dispatch. It is rarely used -- such constructs make it easy to refer to the wrong field or method.

Bob Nystrom

unread,
Sep 10, 2012, 5:04:35 PM9/10/12
to mi...@dartlang.org
On Mon, Sep 10, 2012 at 1:25 PM, Christopher Wright <dhas...@google.com> wrote:
To be pedantic, that C# program wouldn't compile. Make the methods public and slap a 'new' on the method in Derived, and it would have that behavior.

Pedant fight! :D

Default visibility is internal so as long as that's all in one assembly, you shouldn't need public. The absence of "new" should just cause a warning, not an error, I believe.

Of course, the Main() function is bogus, though. It needs to be static and in a class. Also, in defense of any other errors you may find, I haven't written any C# in a few years, so this is all from memory and rusty. :)

- bob

John Messerly

unread,
Sep 10, 2012, 5:11:39 PM9/10/12
to mi...@dartlang.org
On Mon, Sep 10, 2012 at 2:04 PM, Bob Nystrom <rnys...@google.com> wrote:
Default visibility is internal so as long as that's all in one assembly, you shouldn't need public. The absence of "new" should just cause a warning, not an error, I believe.

Members of classes default to private in C#.

Bob Nystrom

unread,
Sep 10, 2012, 5:38:07 PM9/10/12
to mi...@dartlang.org
Drat.

Bob: 0
John: 1

- bob

Reply all
Reply to author
Forward
0 new messages