tags:

views:

304

answers:

6

I have been working for some years in C# and one thing always bugs me. Delegates. They have no state, they are pointers to object methods, and the only way to go when dealing with threads or any other type of parallel programming technique that .net has to offer.

My main concern is that when programming in an object oriented style, the fact that delegates break the paradigm by breaking the notion that if you go Object Oriented then the design phase using UML and CRC should map to the language that you use.

So as the title asks, are delegates real objects or a programming anomaly, something that is required to be done outside the scope of Object Oriented Design.

Is it possible therefore for an object to be an object if it has no state and can a delegate be modelled in UML?

A well-known person once gave a public lecture on astronomy. He described how the earth orbits around the sun and how the sun, in turn, orbits around the center of a vast collection of stars called our galaxy. At the end of the lecture, a little old lady at the back of the room got up and said: "What you have told us is rubbish. The world is really a flat plate supported on the back of a giant tortoise." The scientist gave a superior smile before replying, "What is the tortoise standing on?" "You're very clever, young man, very clever", said the old lady. "But it's turtles all the way down! ---- Stephen Hawkins

I think this relates very well to objects and the fundamental types they sit upon. Can you really say its objects all the way down?

+15  A: 

They're real objects.

When you're modeling with UML it's common to use interfaces. Do they have state? No. Are they any less object-oriented? Of course not.

Of course a delegate can be modeled in UML.

I think they represent a more functional approach, because they are functions that are first class objects. That might concern you, but it doesn't detract from the fact that they are indeed objects.

duffymo
Interfaces are not objects though, they are design patterns. You implement an interface, making sure that your object adheres to the pattern. How would one model a delegate in UML, could you point me to an example. thanks in advanced.
WeNeedAnswers
I said it was common to use interfaces in UML. And no, they aren't design patterns. They are objects with all pure virtual functions. You'd model a delegate as an object with all the methods in the base class. You sound like you're really hung up on UML. It's not a useful obsession.
duffymo
Sorry, when I say design pattern I should have made it clear, they are more like patterns of usage not "Design Patterns" in the common sense. You don't implement an interface as an object. What base class, you thinking of Java there, delegates are implemented differently in C#.
WeNeedAnswers
As for my obsession in UML. UML is a programming language, just not been hooked into a code generator as of yet. It will come. When a system fades away into obscurity (Cobol for example), hopefully the schematic diagrams I draw up in UML will still be around to describe in a metaphysical stance of what was analysed and what we tried to achieve. If I modelled a delegate as you stated, it would not be an accurate representation in c# code.
WeNeedAnswers
Interfaces pre-date UML, and they were part of C++ long before there was a Java or C#. They certainly define types. With regard to base classes, please see Jon Skeet: a delegate derives from either a Delegate or a MulticastDelegate. There are inherited methods, whether you know or use them.
duffymo
UML is *not* a programming language. Cobol has not faded into obscurity. It's running all over the world right now. As for your UML diagrams, they'll be sitting on shared drives, ignored by all those organizations that are still happily running systems developed with real programming languages. You fail to understand UML, objects, or delegates.
duffymo
Cobol is fading into obscurity, nearly all the organizations I have worked with in the last couple of years are moving systems over to modern languages. The only exception I have come across in the UK is a large catalogue company called Argos. What is your problem with UML, you don't think that its relevant?
WeNeedAnswers
Cobol will still be running banks when you and I are retired. It's been fading into obscurity for 20 years. Is UML relevant? Absolutely not. It's fading into obscurity a lot faster than Cobol.
duffymo
Stateless objects are still objects. You seem to have odd ideas about what is and is not an object.
duffymo
Not many banks in the UK running AS400's these days :). And German banks are moving over to functional programming in a big way. I don't see many graduates moving into Cobol, When I left in '97 I was kitted up in Java and Delphi and UML. You got to move with the times, UML is being used heavily out there, the Agents are all marketing themselves as "Agile" not having a clue what it means!, thing is though with languages like python making nice inroads into the mainstream, and all that dreaded interpreted stuff, you need some good designs to keep the code in check.
WeNeedAnswers
Odd Ideas? whats the point of a stateless object? may as well drop OO and go functional/procedural if you think that way. Hey just put all your methods in one big object, make a couple of objects that hold the state, and pass the one object into the other objects methods, thats objects ain't it ;)?
WeNeedAnswers
I agree that not many graduates are moving into Cobol, but that doesn't mean no one is running those older systems. Unless you've worked at a significant number of companies in the UK and Germany and can back up the statement with some data, I'd say you're speculating. I'm basing my view on personal experience at three companies that are part of the Dow Jones in the US and a fourth smaller one that manufactures helicopters. I know UML well. See Fowler: I'm firmly in the "sketchers" camp. MDA is a failure. http://martinfowler.com/bliki/ModelDrivenArchitecture.html
duffymo
Like I said, stateless objects are objects nonetheless. You need to learn a bit more, I'm afraid.
duffymo
Most people I talk too, are currently afraid of the cost of keeping systems on that can not be maintained. I used to do Cobol, so I can't knock the language, made a bit of money in 1999 with a few companies, some I worked with said enough was enough and killed the Cobol off replacing it quick speed with terrible designed software in the latest fad language (I think it was COM+, horrible!). Which companies you work for, genuinely interested. I been around the block a bit, banks, insurance, start-ups, not fussed as long as they pay :)
WeNeedAnswers
I've had two careers: one as a mechanical engineer, another as a software developer, mostly with financial service and insurance firms. I'd say that Microsoft and Jon Skeet would both say that delegates are first-class objects. I'd certainly consider both of them more authoritative than me. Based on the evidence, I agree with them.
duffymo
Maybe an object duffy, but thats piss poor design if you think that an object can get away with just having methods, or members :)
WeNeedAnswers
Object Cobol, that cracks me up.
WeNeedAnswers
Go tell Jon Skeet that he's a piss poor designer. Do you know who he is?
duffymo
Object Cobol? Where did you see that? Or is that just another topic you're bringing in?
duffymo
I think you need to learn a lot more about objects. Your view of what is and is not an object is very narrow, indeed.
duffymo
I done my learning about objects. If you start thinking in a decoupled way that your on the verge of, you may was well throw it away. I'm not saying that separating of data from functions is a bad idea, just that it goes against design principals of Object Design. Your data becomes scoped by using a container object, but that object may as well be a basic array. Maybe the Lisp and Schemers were right all along, maybe objects never worked. heck a program is just tree structure, how stupid am I, wasting all these years on objects :)
WeNeedAnswers
@duffymo: +1 for the trouble. :)
Robert Harvey
If you were paying attention, you'd see that the Lisp and Schemers are no less correct than they've always been. Haven't you noticed what's happening with functional programming? Scala, Erlang, F#? Objects aren't anything special; they're just another attempt to manage complexity. A program *is* just an abstract tree structure.
duffymo
Philosophically speaking, objects are very special and exist outside of the domain of programming. Yes I agree inside of code Objects are nothing special. Where objects come into their own is when speaking to real people (not pogrammers) and trying to convey meaning to their world in a visual format. Most projects I work on, I need to prove that the work I am doing has some value, no Director wants to see lines of code, but diagrams, they can't get enough of. Only problem with Object Design, is that you must carry it through to your code, to work with others, because the parts must fit.
WeNeedAnswers
As for the functional languages, I think that's outside of the scope of this discussion, personally I love them, but then again I like the maths. Lisp and Schemers I feel have the pulse at the moment. No BS in a lisp program, you look at it, you head hurts, but the structures are raw and unsugared and very much closer to AST's than anything I have seen thus far. Just a bugger to work with :)
WeNeedAnswers
Your views on objects reflects more upon your understanding of objects than it does on objects themselves. You've made up your mind what objects are, and it's frankly a relatively shallow understanding. You may wish to research the Actor model, and consider objects-as-Actors as a design paradigm. In such a model, objects would *never* have publicly accessible state since there's no concept of 'return values' in the Actor model (at least, between Actors). Consider as well that some developers consider getters and setters to break encapsulation, and be poor OO design.
kyoryu
@Kyroryu yeah yeah we all read the David West Book (Object Thinking, on sale now at all good MS retailers), but don't confuse the Design stuff to the implementation. This is about Delegates.
WeNeedAnswers
+2  A: 

Yes. They don't break the object oriented paradigm. They just embrace and extend it ;)

mumtaz
+3  A: 

From wikipedia (Object (computer science): In the domain of object-oriented programming an object is usually taken to mean a compilation of attributes (object elements) and behaviors (methods or subroutines) encapsulating an entity. Delegates all are subclassed from the Delegate class in .Net. The Delegate class certainly has attributes (i.e. properties): Method & Target. The class also has behaviors (methods): Combine, CreateDelegate among others.

Delegates are not pointers, as a simple pointer to a method could not encapsulate the 'this' pointer, which delegates do. As Gabe pointed out, delegates also have state, they could be empty (in which case invoking them does nothing) or they could have one or more methods in their list.

Having satisfied the criteria for an object, they are objects.

Q.E.D.

Steve Ellinger
Who's Gabe? None of the folks responding here go by that tag. Wait, now I see - first comment.
duffymo
could you explain that bit about 'this'?
WeNeedAnswers
WeNeedAnswers: When you call a method like `employee.GetSalary()`, the `GetSalary` method gets called with the value of `employee` as an invisible first parameter. Inside of the `GetSalary` method, you access that parameter with the keyword `this`. When you create a delegate for `employee.GetSalary`, it creates an object with both a pointer to the `GetSalary` method and the value for `employee`.
Gabe
Creates or Calls, I thought that it just calls the method on the already created object on the current thread that its operating on. Where does the 'this' come into it, I thought that would be a given, given that the object being called knows exactly the context to which it is being called in and in which scope.
WeNeedAnswers
WeNeedAnswers: *Creating* a delegate *creates* an object holding a function pointer and a parameter. *Calling* that delegate *calls* that function pointer with the included parameter.
Gabe
WeNeedAnswers: the code for the method is loaded into memory once, no matter how many instances of the class are created, therefore the way the code in the method understands the context is with the hidden parameter that is a reference to the instance, you access this reference with the 'this' keyword.
Steve Ellinger
Oh I get where your coming from, I was thinking elsewhere, thanks for your explanation.
WeNeedAnswers
+7  A: 

It's become clear that this point isn't going to get across without somebody wielding the closure hammer. No, not the "close this question" hammer.

Action @ICanHazState()
{
    int callcount = 0;
    Action retval = delegate {
       System.MessageBox("I haz bin calld " + callcount.ToString() + " tims b4");
       if (++callcount > 5) throw new InvalidOperationException("Call limit exceeded.  Kaboom!");
    };
    return retval;
}

Complete compilable example here

More complex example (requires C# 4 e.g. Visual Studio 2010)

Ben Voigt
I think your hammer would be more effective if you show the output of a small program using the closure.
Gabe
nice code, what does it prove?
WeNeedAnswers
@WeNeedAnswers: It's just a little delegate wanting to show that **it has state**.
Ben Voigt
what happens when @ICanHazeState() goes out of scope, doesn't callCount get wiped out?
WeNeedAnswers
@WeNeedAnswers: Click the link to the example, observe the behavior.
Ben Voigt
WeNeedAnswers: Every time you call `ICanHazState`, a new `callCount` gets created, entirely separate from all the other ones that have been created.
Gabe
Well, in the end the variable is hoisted into a helper class. But you wouldn't say that a `List<T>` doesn't have content just because it uses a helper object (array) to hold its content. Here the state is held in a helper object as well, but as soon as `ICanHazState` returns the delegate has sole ownership of the state object, so I'd definitely say the "the state belongs to the delegate". And as far as the C# language and you, the programmer, are concerned, that local variable was *captured by the delegate*.
Ben Voigt
where is CallCount stored?
WeNeedAnswers
In a helper object used by the delegate to store state.
Ben Voigt
I love that this answer destroys the obvious pro dynamic languages flame bait the OP tried.
eglasius
+1 (+10 if I could) for very witty example ("Kitteh sad" had me in fits)
smirkingman
Can you access the Helper Object outside of the scope of the delegate? Can you change the scope of the local variable? If none of this is valid, then sorry its not OOP, its something else, and proves to me that its not Object thinking at all.
WeNeedAnswers
Can you show me an example that doesn't rely on the magic that is Console :)
WeNeedAnswers
@WeNeedAnswers: The helper object can only be accessed by the delegate itself, and the method that initializes it (`ICanHazState`). I don't see how you claim this means it is not OOP, since *encapsulation* is one of the fundamental principles of OOP. It's possible to share objects with the delegate of course, using references. Maybe I'll work up an example later.
Ben Voigt
thanks. Yes I understand the mechanics of it. So your saying to get the magic to work you would have to pass in a reference into the delegate which is stored outside of the delgate to get at the insides of the delegate. I think this breaks the open/closed principal of OO. The State of the delegate is only accessible by passing in a ref of another object, thus the external object becomes the state object. Don't get me wrong, I loved the example, and will use it, I got some python code that will move across with the technique above, but for argument sake its not true OO.
WeNeedAnswers
The complex example? Does that compile? Thanks for your efforts with the coding, its really cool that you do that. Just need to look at it in depth before I comment though :)
WeNeedAnswers
Nice example, but do you really think that passing in an out parameter (another object) proves that the delegate is an object, or a workaround for the fact that a delegate isn't an object and this is the only way to get at its internals?
WeNeedAnswers
The complex example needs C# 4, it will not compile in the version of mono used on ideone. Was that not clear from my post? Also, in case you didn't notice, those out parameters, which you called objects, are also delegates. I think that means I win.
Ben Voigt
@Ben ha ha. you win indeed , I think not :). Just because it is classed as a first class type, does not mean its an object. Nice try. In functional programming as you jolly well know, you pass functions round as standard. But in a functional language I wouldn't dare mention the Class word, they would kill me for being a half breed impure ;) Unless your saying that function declarations in say Haskell are really objects? If so its a different way of thinking about functions than the functional world might think. It would change the functional paradigm on its head. thanks once again.
WeNeedAnswers
I'm saying that objects don't need to be based on a class model (which is a prerequisite for inheritance). And yes, Haskell functions have everything necessary to make objects. Read http://homepages.cwi.nl/~ralf/OOHaskell/
Ben Voigt
Nice thinking there, I will have to give it more thought. Its something I have not looked at. Give me a day and will get back to you on this. Its an interesting concept of objects without hierarchy. I think your on to something there. Will also read the pdf link. thanks. Sounds a lot like dynamic programming in the style of JavaScript prototyping as opposed to python. I am a heavy user of interfaces, maybe this is a way to go. I got a feeling though its moving into functional programming where they call classes something else. Sounds like functional Composition.
WeNeedAnswers
maybe I should scrap UML and go back to SSADM :)
WeNeedAnswers
Quick question, how far do you think you can take this using delegates as objects, a whole program written from start to finish? There must be some overhead if you tried this in C#, I know that this is what f# does, not too sure on the .net types used are in f# declarations. You got my head buzzing now, thanks.
WeNeedAnswers
I think I found my answer to the above. It will blow the stack space :)
WeNeedAnswers
Can you imagine say 200 delegates on the stack representing say a person. Heavens forbid all those addresses. And don't get me started on those damn orders and orderlines. :)
WeNeedAnswers
Well, delegates should be very effective in continuation-passing style, which requires tail calls to avoid exhausting the stack. I don't know if you can convince the C# compiler to generate tail calls to delegates. Eric Lippert, one of the C# designers, wrote about CPS recently [part 1](http://blogs.msdn.com/b/ericlippert/archive/2010/10/21/continuation-passing-style-revisited-part-one.aspx), [part 2](http://blogs.msdn.com/b/ericlippert/archive/2010/10/22/continuation-passing-style-revisited-part-two-handwaving-about-control-flow.aspx).
Ben Voigt
Yes Ben, tail recursion would solve this, but you may as well go functional f#. Only problem I have with that is that I like the ease of modelling you get with OOP over FOP of business domains. Would it lead to abuse?
WeNeedAnswers
Nice articles on CPS. Had a quick browse, will look at them more in depth.
WeNeedAnswers
A: 

Delegates are Objects with proviso.

  • They can not be inherited. Open Closed Principal is broken.
  • They do exhibit state, although the state can only be obtained by an Object Reference to the state by another object passed into it.
  • They do have an internal structure that does seem to follow Object thinking. However, because there is no way to extend the delegate, change its behaviour or make alterations to the code, they could be described in the same fashion as the "primitive" types such as string, int etc

My conclusions on this is that Delgates are not true Objects, but necessary scaffolding to make the .net framework work. It is an object, but only in the sense that it is a primitive type.

A delegate is a form of type-safe function pointer.

If you feel that my views on this are incorrect then please leave your answer, with proof that a delegate is an object. I have seen a lot of inflammatory nonsense being posted, and some remarkably cracking answers which I appreciate the time and effort for. I did mark this as an answer, but after the comments below, I have left this as a suggested answer, and left it open. I am entitled to my opinion, some people may find it incorrect, but unless this is discussed openly and logically then I as the creator of this question will never receive an answer where I feel that it is definitive.

WeNeedAnswers
This is bullshit. You answered and accepted your own question. This is obviously not the intent of SO. "not true Objects" - only your misinformed opinion, nothing more. You aren't the arbiter of "true Objects".
duffymo
I love the fact that this (very poor) answer also describes string as a primitive, when it isn't. In fact the key poor in this answer seems to hinge on the fact that they can't be inherited; **many, many** types can't be inherited; that doesn't change their nature. Poor show.
Marc Gravell
Strings were called primitives back in the days of Framework 1.0. Then the Document Squad at MS realised it was causing confusion and changed it. @DuffyMo, I will release my answer, if you can do better than just commenting please do. Please write some proof that Delegates act and are true objects.
WeNeedAnswers
@Duffy, next time you be telling me that Object Cobol really is Objects. Where do you draw the line? A Console application that calls another Console App an object? Is a WCF component an object? Is a mathematical equation an object? In that case the entire Haskell programming languages can do objects. Please reply to what you think an object is. I would be most interested.
WeNeedAnswers
@Marc Gravell. Most of the string functions (please note, not calling them methods) when acting on so called string objects, don't actually change the state of the object, but create a new string. The stringBuilder is an Object, but strings are treated as immutable types in c#
WeNeedAnswers
http://msdn.microsoft.com/en-us/library/ms228360(VS.80).aspx, old document for 2005. Please note the arbitary statements banded about primitive types.
WeNeedAnswers
So is a tuple an Object, Record structure. When did these things become objects. C# is not a "pure" object language, get over it, it don't make it any less of a language.
WeNeedAnswers
Immutability is orthogonal to this discussion; re the discussion of methods vs functions - again, you're trying to pick arbitrary terminlogy to suit your argument.
Marc Gravell
Terminology is fundamental to this argument. We are after all talking about terminology, taxonomy and classification. As for arbitrary, I don't think it is. Without history we can not see what we have done, and where we are going. You can not re-write history to suit your needs, although it does happen, else you may as well not describe anything in the first place. A rose is still a rose by any other name, does it not smell sweetly? As for immutable, for heavens sake why do you think objects were created in languages in the first place, it is to encapsulate mutable state.
WeNeedAnswers
If an object becomes immutable through smoke and mirrors such as syntax sugar, as in the case for strings do you think that this is a true representation of an object?
WeNeedAnswers
string x = "hello"; x = "fred". the actual value of x is re-written in another part of memory and the "hello" value is discarded eventually. I'm not saying that I don't like this, I do, it makes my job a lot easier, and my brain can cope with the distinction between an object and a primitive type. But the classification must be correct. I would not try to model a string in UML as it is regarded outside of scope.
WeNeedAnswers
Nobody cares; your trollish behavior deserves banishment more than answers.
duffymo
duffy your acting like an idiot, how old are you again?
WeNeedAnswers
+2  A: 

Define "object."

Your definition seems to be that to be an object, 'thing' must have mutable state and be inheritable.

By that definition, delegates are not objects. However, I consider that definition to be extremely, extremely limited. Entire categories of 'objects' in real-world applications fail by that definition. Functors, to start with. Many decorator types would also fail by that definition, as well as things like filter objects.

If you go back to Smalltalk, for instance, both true and false are objects. By your definition, they would not be.

kyoryu
Exactly right. Java enums wouldn't qualify as objects either, yet they inherit from Enum. The JVM certainly sees them as objects.
duffymo
This is C#. Not Java.
WeNeedAnswers
Same with C#; no different. http://www.csharp-station.com/Tutorials/lesson17.aspx
duffymo
Is a string an Object, now come on, be honest, you think that a string is really not an array of chars in disguise. Enums, sugar syntax for a read only associative array?
WeNeedAnswers
@WeNeedAnswers: Fine, then, as I said in my answer - define "object."
kyoryu
@kyoryu, I think if you can duplicate something in a language using the constructs of the language, including the syntax sugar that the syntax of the language uses, then I would say that this is an object. From that definition, if you can not duplicate the functionality, the syntax sugar or replace of such article in code then this is not an object. Under this definition, a String, an Enum and a delegate are not objects. As for objects outside of the language specifics, take a look at the OMG's definition, or take a look at the marvellous David Wests book on Object Thinking.
WeNeedAnswers