Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. .NET 2.0 features

.NET 2.0 features

Scheduled Pinned Locked Moved The Lounge
csharpc++comarchitecturequestion
43 Posts 17 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Jorgen Sigvardsson

    Hmmmmm! Wait a minute. How can that work? Suppose I have this: (bear with me, I'm not fluent in generics syntax)

    template <typename T> class SomeClass {
    public void DoSomething(T obj) {
    obj.SomeMethod();
    }
    }

    class X {
    public void SomeMethod() { }
    }

    class Y {
    public void SomeMethod() { }
    }

    SomeClass<X> anObject = new SomeClass<X>();
    anObject.DoSomething(new X());
    SomeClass<Y> yetAnotherObject = new SomeClass<X>();
    anObject.DoSomething(new Y());

    Since classes X and Y are not directly related, how does SomeClass.DoSomething() call the correct method? Are method calls in MSIL made by method name lookup?

    -- This Episode Has Been Modified To Fit Your Primitive Screen

    J Offline
    J Offline
    Judah Gabriel Himango
    wrote on last edited by
    #41

    Jörgen Sigvardsson wrote:

    how does SomeClass.DoSomething() call the correct method? Are method calls in MSIL made by method name lookup?

    In short, in CLR generics, I can only put a SomeMethod call in there if T is guaranteed to have a SomeMethod() method. I can guarantee such by using interfaces (kind of like C++ pure abstract classes, except no implementation). This is a key difference between C++ templates and CLR generics; one reason why C++ templates are more powerful simply because they are a compile-time mechanism (which is fine, since C++ doesn't interop templates with other languages, since they get compiled down to real class instances with the real object in place of T), whereas CLR generics are more limiting because they are runtime-instantiated and are supported across disparate languages; they don't get compiled down to new SomeClass instances, with your type replacing T. Such deep runtime support of generics has some benefits: - we can do things like expose generic instances, say a List<int> to all other .NET assemblies, be they C#, VB.NET, IronPython, C++/CLI, etc. - we can use reflection to investigate, at runtime, the type of a List<T> instance and it will correctly give back a List<int> type in this case. This is something Java's generics fail to do, since Java generics are entirely syntax candy, no runtime support. But putting generics in the runtime also has some limitations: In C++, if there isn't SomeMethod on the template instance you've instantiated, you get a compile-time error. But for CLR generics, the compiler simply will not let you put in a method call into a generic class if the type doesn't support that method. And since the generic class type is, by default, System.Object as you mentioned, there is no SomeMethod on System.Object. To get around this, the CLR has what's called a constraint. You can constrain the T in the generic class to any object that supports some interface, that inherits from some type, or has a default constructor, or is a value type, and so on. Lots of constraint possibilities. If I wanted to achieve what you posted in the above C++ code, you'd do it like this:

    interface ISomeMethod
    {
    void DoSomething();
    }

    class SomeClass<T>
    where T : ISomeMethod // Only allow this generics class to be used with an object that implements the ISomeMethod interface.
    {
    void DoSomething(T obj)
    {
    obj.DoSomething(); // this works, because of the constraint

    J 1 Reply Last reply
    0
    • C Christian Graus

      I'm interested ( in light of the post below ) to know how many people have taken to the new 2.0 features ? We all use typed containers, I am sure, but how often do you use an anonymous method or iterators ? As I said on that thread, I used my first anonymous method, because it struck me as the ideal solution as I worked on it, before it's never seemed appropriate. I wonder if I'm just not in the habit yet, or this was truly the first time they were the right tool for the job. I love the idea of iterators, but I don't think I've used them in production code yet, and I imagine I need to look out for chances to change my mindset to be using them. How about you ?

      Christian Graus - Microsoft MVP - C++ Metal Musings - Rex and my new metal blog

      S Offline
      S Offline
      Stuart Dootson
      wrote on last edited by
      #42

      Well - I don't use .NET, I use C++ with Boost[^], but I make use of the Boost equivalents of iterators[^] and anonymous functions[^]. Iterators are for anything that has a concept of enumerability (mostly files of wacky formats for me). As an example - I have an application where I have to read a big-endian file. So, I wrap up a file iterator and a byte reverser together and I get an iterator that gives me little endian results (joy!). I use anonymous methods pretty much wherever I use Standard Template Library algorithms. Also, in conjunction with generic function objects[^] - customising some functionality by passing in an adapted function.

      1 Reply Last reply
      0
      • J Judah Gabriel Himango

        Jörgen Sigvardsson wrote:

        how does SomeClass.DoSomething() call the correct method? Are method calls in MSIL made by method name lookup?

        In short, in CLR generics, I can only put a SomeMethod call in there if T is guaranteed to have a SomeMethod() method. I can guarantee such by using interfaces (kind of like C++ pure abstract classes, except no implementation). This is a key difference between C++ templates and CLR generics; one reason why C++ templates are more powerful simply because they are a compile-time mechanism (which is fine, since C++ doesn't interop templates with other languages, since they get compiled down to real class instances with the real object in place of T), whereas CLR generics are more limiting because they are runtime-instantiated and are supported across disparate languages; they don't get compiled down to new SomeClass instances, with your type replacing T. Such deep runtime support of generics has some benefits: - we can do things like expose generic instances, say a List<int> to all other .NET assemblies, be they C#, VB.NET, IronPython, C++/CLI, etc. - we can use reflection to investigate, at runtime, the type of a List<T> instance and it will correctly give back a List<int> type in this case. This is something Java's generics fail to do, since Java generics are entirely syntax candy, no runtime support. But putting generics in the runtime also has some limitations: In C++, if there isn't SomeMethod on the template instance you've instantiated, you get a compile-time error. But for CLR generics, the compiler simply will not let you put in a method call into a generic class if the type doesn't support that method. And since the generic class type is, by default, System.Object as you mentioned, there is no SomeMethod on System.Object. To get around this, the CLR has what's called a constraint. You can constrain the T in the generic class to any object that supports some interface, that inherits from some type, or has a default constructor, or is a value type, and so on. Lots of constraint possibilities. If I wanted to achieve what you posted in the above C++ code, you'd do it like this:

        interface ISomeMethod
        {
        void DoSomething();
        }

        class SomeClass<T>
        where T : ISomeMethod // Only allow this generics class to be used with an object that implements the ISomeMethod interface.
        {
        void DoSomething(T obj)
        {
        obj.DoSomething(); // this works, because of the constraint

        J Offline
        J Offline
        Jorgen Sigvardsson
        wrote on last edited by
        #43

        Thanks for the clarification! Much obliged. :)

        -- Touch eyeballs to screen for cheap laser surgery

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups