I am working with ESRI's ArcObjects COM Library, i am trying really hard to figure out what type "selected" should be:
IMxDocument doc = m_application.Document as IMxDocument;
object selected = doc.SelectedItem;
SelectedItem returns a comobject (Not Null), generally representing the data type that is currently selected. However i do not have the faintest idea what type i am supposed to cast it to. When i debug it, i don't really see anything useful:
http://imgur.com/Yfo6G
(watch debug after the value is set)
ESRI's ArcObjects library is huge, and is pretty poorly documented, i simply cannot figure it out. I even went so far as to manually check about 50 or so interfaces that i thought it should be.
Does anyone have any ideas how i can figure this out?
EDIT To clarify their documentation is absolutely no help, neither is their forums.
After reading your question, the answers, and the comments, you may have to write a utility to find the answer by brute force.
Use reflection to scrape a list of interfaces out of your interop assembly, then simply loop over this list and see if your object supports each interface in turn.
Update
Some sample code:
object unknown = //your com object...
Type someComObjectType = typeof(ExampleTypeInInteropAssembly);
Assembly interopAssembly = someComObjectType.Assembly;
Func<Type, bool> implementsInterface = iface =>
{
try
{
Marshal.GetComInterfaceForObject(unknown, iface);
return true;
}
catch (InvalidCastException)
{
return false;
}
};
List<Type> supportedInterfaces = interopAssembly.
GetTypes().
Where(t => t.IsInterface).
Where(implementsInterface).
ToList();
if (supportedInterfaces.Count > 0)
{
supportedInterfaces.ForEach(Console.WriteLine);
}
else
{
Console.WriteLine("No supported interfaces found :(");
}
I'm not familiar with that library, but I can give some suggestions. Once you look at the problem from the point of view of COM you'll see that there is no simple answer.
(Do keep in mind that that in COM all objects are just objects, and that the only requirement is that it must support IUNKNOWN (and possibly other interfaces). So the answer to the question "what type of object it is" can often have more than one answer.)
The important thing to remember is that in COM the list of interfaces for an object is not defined in any sort of metadata like it is in .NET (except that a library usually provides an optional type library as a form of documentation for development tools -- more on that in a minute).
The list of interfaces is officially defined only by the results of calling IUNKNOWN's QueryInterface() method -- that is, it's defined entirely by the result of executing code.
Some times the list might be hard-coded. Often, the list might not be known until runtime, and it might not even be known until somebody asks. The only rule is that the list of interfaces needs to be stable and what I call sensible: the list cannot change over time for a given object instance; it must support IUNKNOWN, which sometimes people forget; if it supports a derived interface, it must support its base; and a couple of other I'm sure I'm forgetting.
That last point is crucial to your problem: COM doesn't know a priori what interfaces are supported by any object. The .NET runtime doesn't know either -- not from COM anyway. The only way for .NET to know would be if the Type Library for the object says that the object returned is of a specific interface. Lacking that, all you have is an IUNKNOWN pointer and you have to ask for specific interfaces via code and see if you get an answer other than NULL.
Since the type of the SelectedItem propery is object, it means that the type library simply says "the return type is an interface pointer of type IUNKNOWN" (it might be IDISPATCH, but the principle stands). The exact type obviously depends on runtime circumstances -- "what happens to be selected right now".
(In .NET, the return type is actually System.__ComObject because you don't get a naked interface pointer but a COM callable wrapper which a .NET based proxy to the object)
You are at the mercy of the (poor?) documentation of the library to get a clue on what kinds of interfaces the returned object might support. Lacking that, code like Chibacity's might get you a partial list as well (I have not reviewed that code). Ultimately, you probably want to use that code to get a list of candidate interfaces during debugging.
Once you know a few possibilities that interest you, you can save yourself some typing trouble by just using the C# as operator (which causes the COM callable wrapper to issue the corresponding COM spells against the native object).
I aggree that the documentation is lacking at certain places but the help is pretty specific in your case:
Remarks
This property returns a reference to the currently selected item in
the table of contents. The return is an IUnknown because there
are several possbile objects the selected item can be.
When working in the Display tab, the reference could be to a Map
object if you have a data frame selected, one of the Layer objects
(FeatureLayer, FDOGraphicsLayer, etc) if you have a layer selected, or
a LegendGroup if you have a unique value or heading selected.
In the Source tab, the reference can be to any of the above objects
plus a Table, FeatureDataset, or Workspace.
In the case where more than one item is selected, the reference is to
a Set object.
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#/SelectedItem_Property/000v00000124000000/
I'am affraid there is no way to list the interfaces implemented by a com object. However, you still can brute force it by querying it against a list of interface you are interested in.
Edit:
Some code that may help:
foreach(Type comInterfacType in comInterfaceTypesIAmInterestedIn) {
IntPtr comInterface = Marshal.GetComInterfaceForObject(o, comInterfaceType);
if(comInterface != IntPtr.Zero) {
Console.WriteLine("o implements " + comInterfaceType);
Marshal.ReleaseComObject(o);
}
}
(would have added this as a comment, but I'm a noob and my rep is insufficient)
It's been awhile since I've worked with ArcObjects, but I do remember that the object model was ridiculously large and poorly documented. That said, doesn't IMxDocument.SelectedItem refer to the item that is selected in the TOC/layers control? If so, wouldn't it return an instance of IMap or ILayer?
try selected.GetType().ToString();
It should give the the type of object that it is.
Try read the docs. If the SDK does not help, try read the type library in the OLEView utility that is shipped with Windows Resource Kit and Visual C++.
Related
If I have various subclasses of something, and an algorithm which operates on instances of those subclasses, and if the behaviour of the algorithm varies slightly depending on what particular subclass an instance is, then the most usual object-oriented way to do this is using virtual methods.
For example if the subclasses are DOM nodes, and if the algorithm is to insert a child node, that algorithm differs depending on whether the parent node is a DOM element (which can have children) or DOM text (which can't): and so the insertChildren method may be virtual (or abstract) in the DomNode base class, and implemented differently in each of the DomElement and DomText subclasses.
Another possibility is give the instances a common property, whose value can be read: for example the algorithm might read the nodeType property of the DomNode base class; or for another example, you might have different types (subclasses) of network packet, which share a common packet header, and you can read the packet header to see what type of packet it is.
I haven't used run-time-type information much, including:
The is and as keywords in C#
Downcasting
The Object.GetType method in dot net
The typeid operator in C++
When I'm adding a new algorithm which depends on the type of subclass, I tend instead to add a new virtual method to the class hierarchy.
My question is, when is it appropriate to use run-time-type information, instead of virtual functions?
When there's no other way around. Virtual methods are always preferred but sometimes they just can't be used. There's couple of reasons why this could happen but most common one is that you don't have source code of classes you want to work with or you can't change them. This often happens when you work with legacy system or with closed source commercial library.
In .NET it might also happens that you have to load new assemblies on the fly, like plugins and you generally have no base classes but have to use something like duck typing.
In C++, among some other obscure cases (which mostly deal with inferior design choices), RTTI is a way to implement so-called multi methods.
This constructions ("is" and "as") are very familiar for Delphi developers since event handlers usually downcast objects to a common ancestor. For example event OnClick passes the only argurment Sender: TObject regardless of the type of the object, whether it is TButton, TListBox or any other. If you want to know something more about this object you have to access it through "as", but in order to avoid an exception, you can check it with "is" before. This downcasting allows design-type binding of objects and methods that could not be possible with strict class type checking. Imagine you want to do the same thing if the user clicks Button or ListBox, but if they provide us with different prototypes of functions, it could not be possible to bind them to the same procedure.
In more general case, an object can call a function that notifies that the object for example has changed. But in advance it leaves the destination the possibility to know him "personally" (through as and is), but not necessarily. It does this by passing self as a most common ancestor of all objects (TObject in Delphi case)
dynamic_cast<>, if I remember correctly, is depending on RTTI. Some obscure outer interfaces might also rely on RTTI when an object is passed through a void pointer (for whatever reason that might happen).
That being said, I haven't seen typeof() in the wild in 10 years of pro C++ maintenance work. (Luckily.)
You can refer to More Effective C# for a case where run-time type checking is OK.
Item 3. Specialize Generic Algorithms
Using Runtime Type Checking
You can easily reuse generics by
simply specifying new type parameters.
A new instantiation with new type
parameters means a new type having
similar functionality.
All this is great, because you write
less code. However, sometimes being
more generic means not taking
advantage of a more specific, but
clearly superior, algorithm. The C#
language rules take this into account.
All it takes is for you to recognize
that your algorithm can be more
efficient when the type parameters
have greater capabilities, and then to
write that specific code. Furthermore,
creating a second generic type that
specifies different constraints
doesn't always work. Generic
instantiations are based on the
compile-time type of an object, and
not the runtime type. If you fail to
take that into account, you can miss
possible efficiencies.
For example, suppose you write a class that provides a reverse-order enumeration on a sequence of items represented through IEnumerable<T>. In order to enumerate it backwards you may iterate it and copy items into an intermediate collection with indexer access like List<T> and than enumerate that collection using indexer access backwards. But if your original IEnumerable is IList why not take advantage of it and provide more performant way (without copying to intermediate collection) to iterate items backwards. So basically it is a special we can take advantage of but still providing the same behavior (iterating sequence backwards).
But in general you should carefully consider run-time type checking and ensure that it doesn't violate Liskov Substituion Principle.
Apparently the following is valid in c# 4.0 regardless of the type of the object returned by GetADynamicThing()
dynamic d = GetADynamicThing();
d.Foo();
And if the runtime type of d does not contain a method Foo(), a RunTimeBinderException is thrown.
Will there be an easy way to determine if Foo() exists on d?
Otherwise, we're stuck doing old school reflection on the object, or relying on try-catch. Not sure I like either approach.
Update: So we have currently have 3 options:
Reflection
Catch Exception
Hope GetADynamicThing() returns what you expect it to return
Number 3 seems to be the targeted usage of dynamic which in COM situations is great. The reason I asked the question originally was in response to doing something like this i.e. using methods some arbitrarily created object. This very much seems like the wrong situation to be using dynamic.
The dynamic type is not meant to be a replacement for System.Object. If you have NO idea what is being returned, using System.Object or a concrete interface in your API is still a better approach than using dynamic, even in C# 4.
Dynamic is very useful if you know, basically, what you are returning. You should treat a member being missing (ie: Foo) as an exceptional case, in which case the exception is a reasonable way of handling this.
The whole point of the dynamic type is to assume member presence.
If you really need to know before you call the method use reflection or better yet create a concrete type the implements an interface that declares Foo(). I would contend that if you need to check if Foo() is a member of a dynamic type, then dynamic is the wrong choice for you. It sounds like you need static type checking.
If your architecture is so open such that you have no idea what is being returned by GetADynamicThing then you should either catch the exception or use reflection somehow. However, in most scenarios, you will have a good idea of what you should be getting and can make some assumptions.
If there is no way to find out right now, I hope they do.
Maintenance nightmare
Isn't it much more elegant and neat to have an IStringable interface?
Who needs this Type.FullName object returned to us?
EDIT: everyone keeps asking why do I think it's more elegant..
Well, it's just like that, instead of IComparable, object would have CompareTo method, that by default throws an exception or returns 0.
There are objects that cannot and should not be described as a string. object could have equally returned string.Empty. Type.FullName is just an arbitrary choice..
And for methods such as Console.Write(object), I think it should be: Write(IStringable).
However, if you are using WriteLine to anything but strings (or something that its ToString is obvious such as numbers), it seems to me it's for debugging mode only..
By the way - how should I comment to you all? Is it okay that I post an answer?
There are three virtual methods that IMHO should have never been added to System.Object...
ToString()
GetHashCode()
Equals()
All of these could have been implemented as you suggest with an interface. Had they done so I think we'd be much better off. So why are these a problem? Let's just focus on ToString():
If ToString() is expected to be implemented by someone using ToString() and displaying the results you have an implicit contract that the compiler cannot enforce. You assume that ToString() is overloaded, but there is no way to force that to be the case.
With an IStringable you would only need to add that to your generic type-constraint or derive your interface from it to require it's usage on implementing objects.
If the benefit you find in overloading ToString() is for the debugger, you should start using [System.Diagnostics.DebuggerDisplayAttribute].
As for needing this implementation for converting objects to strings via String.Format(), and/or Console.WriteLine, they could have deferred to the System.Convert.ToString(object) and checked for something like 'IStringable', failing over to the type's name if not implemented.
As Christopher Estep points out, it's culture specific.
So I guess I stand alone here saying I hate System.Object and all of it's virtual methods. But I do love C# as a whole and overall I think the designers did a great job.
Note: If you intend to depend upon the behavior of ToString() being overloaded, I would suggest you go ahead and define your IStringable interface. Unfortunatly you'll have to pick another name for the method if you really want to require it.
more
My coworkers and I were just speaking on the topic. I think another big problem with ToString() is answering the question "what is it used for?". Is it Display text? Serialization text? Debugging text? Full type name?
Having Object.ToString makes APIs like Console.WriteLine possible.
From a design perspective the designers of the BCL felt that the ability to provide a string representation of an instance should be common to all objects. True full type name is not always helpful but they felt the ability to have customizable representation at a root level outweighed the minor annoyance of seeing a full type name in output.
True you could implement Console.WriteLine with no Object.ToString and instead do an interface check and default to the full name of the type if the interface was not present. But then every single API which wanted to capture the string representation of an object instance would have to implement this logic. Given the number of times Object.ToString is used just within the core BCL, this would have lead to a lot of duplication.
I imagine it exists because it's a wildly convenient thing to have on all objects and doesn't require add'l cruft to use. Why do you think IStringable would be more elegant?
Not at all.
It doesn't need to be implemented and it returns culture-specific results.
This method returns a human-readable string that is culture-sensitive. For example, for an instance of the Double class whose value is zero, the implementation of Double..::.ToString might return "0.00" or "0,00" depending on the current UI culture.
Further, while it comes with its own implementation, it can be overriden, and often is.
Why make it more complicated? The way it is right now basically establishes that each and every object is capable of printing its value to a string, I can't see anything wrong with that.
A "stringable" representation is useful in so many scenarios, the library designers probably thought ToString() was more straightforward.
With IStringable, you will have to do an extra check/cast to see if you can output an object in string format. It's too much of a hit on perf for such a common operation that should be a good thing to have for 99.99% of all objects anyway.
Mmmm, so it can be overridden in derived classes possibly?
Structs and Objects both have the ToString() member to ease debugging.
The easiest example of this can be seen with Console.WriteLine which receives a whole list of types including object, but also receives params object[] args. As Console is often a layer on-top of TextWriter these statements are also helpful (sometimes) when writing to files and other streams (sockets).
It also illustrates a simple object oriented design that shows you interfaces shouldn't be created just because you can.
My new base class:
class Object : global::System.Object
{
[Obsolete("Do not use ToString()", true)]
public sealed override string ToString()
{
return base.ToString();
}
[Obsolete("Do not use Equals(object)", true)]
public sealed override bool Equals(object obj)
{
return base.Equals(this, obj);
}
[Obsolete("Do not use GetHashCode()", true)]
public sealed override int GetHashCode()
{
return base.GetHashCode();
}
}
There's indeed little use of having the Type.FullName returned to you, but it would be even less use if an empty string or null were returned. You ask why it exists. That's not too easy to answer and has been a much debated issue for years. More then a decade ago, several new languages decided that it would be convenient to implicitly cast an object to a string when it was needed, those languages include Perl, PHP and JavaScript, but none of them is following the object orientation paradigm thoroughly.
Approaches
Designers of object oriented languages had a harder problem. In general, there were three approaches for getting the string representation of an object:
Use multiple inheritance, simply inherit from String as well and you can be cast to a string
Single inheritance: add ToString to the base class as a virtual method
Either: make the cast operator or copy constructor overloadable for strings
Perhaps you'd ask yourself Why would you need a ToString or equiv. in the first place? As some others already noted: the ToString is necessary for introspection (it is called when you hover your mouse over any instance of an object) and the debugger will show it too. As a programmer, you know that on any non-null object you can safely call ToString, always. No cast needed, no conversion needed.
It is considered good programming practice to always implement ToString in your own objects with a meaningful value from your persistable properties. Overloads can help if you need different types of representation of your class.
More history
If you dive a bit deeper in the history, we see SmallTalk taking a wider approach. The base object has many more methods, including printString, printOn etc.
A small decade later, when Bertrand Meyer wrote his landmark book Object Oriented Software construction, he suggested to use a rather wide base class, GENERAL. It includes methods like print, print_line and tagged_out, the latter showing all properties of the object, but no default ToString. But he suggests that the "second base object ANY to which all user defined object derive, can be expanded", which seems like the prototype approach we now know from JavaScript.
In C++, the only multiple inheritance language still in widespread use, no common ancestor exists for all classes. This could be the best candidate language to employ your own approach, i.e. use IStringable. But C++ has other ways: you can overload the cast operator and the copy constructor to implement stringability. In practice, having to be explicit about a to-string-implementation (as you suggest with IStringable) becomes quite cumbersome. C++ programmers know that.
In Java we find the first appearance of toString for a mainstream language. Unfortunately, Java has two main types: objects and value types. Value types do not have a toString method, instead you need to use Integer.toString or cast to the object counterpart. This has proven very cumbersome throughout the years, but Java programmers (incl. me) learnt to live with it.
Then came C# (I skipped a few languages, don't want to make it too long), which was first intended as a display language for the .NET platform, but proved very popular after initial skepticism. The C# designers (Anders Hejlsberg et al) looked mainly at C++ and Java and tried to take the best of both worlds. The value type remained, but boxing was introduced. This made it possible to have value types derive from Object implicitly. Adding ToString analogous to Java was just a small step and was done to ease the transition from the Java world, but has shown its invaluable merits by now.
Oddity
Though you don't directly ask about it, but why would the following have to fail?
object o = null;
Console.WriteLine(o.ToString());
and while you think about it, consider the following, which does not fail:
public static string MakeString(this object o)
{ return o == null ? "null" : o.ToString(); }
// elsewhere:
object o = null;
Console.WriteLine(o.MakeString());
which makes me ask the question: would, if the language designers had thought of extension methods early on, the ToString method be part of the extension methods to prevent unnecessary NullPointerExceptions? Some consider this bad design, other consider it a timesaver.
Eiffel, at the time, had a special class NIL which represented nothingness, but still had all the base class's methods. Sometimes I wished that C# or Java had abandoned null altogether, just like Bertrand Meyer did.
Conclusion
The wide approach of classical languages like Eiffel and Smalltalk has been replaced by a very narrow approach. Java still has a lot of methods on Object, C# only has a handful. This is of course good for implementations. Keeping ToString in the package simply keeps programming clean and understandable at the same time and because it is virtual, you can (and should!) always override it, which will make your code better apprehendable.
-- Abel --
EDIT: the asker edited the question and made a comparison to IComparable, same is probably true for ICloneable. Those are very good remarks and it is often considered that IComparable should've been included in Object. In line with Java, C# has Equals and not IComparable, but against Java, C# does not have ICloneable (Java has clone()).
You also state that it is handy for debugging only. Well, consider this everywhere you need to get the string version of something (contrived, no ext. methods, no String.Format, but you get the idea):
CarInfo car = new CarInfo();
BikeInfo bike = new BikeInfo();
string someInfoText = "Car " +
(car is IStringable) ? ((IStringable) car).ToString() : "none") +
", Bike " +
(bike is IStringable) ? ((IStringable) bike).ToString() : "none");
and compare that with this. Whichever you find easier you should choose:
CarInfo car = new CarInfo();
BikeInfo bike = new BikeInfo();
string someInfoText = "Car " + car.ToString() + ", Bike " + bike.ToString();
Remember that languages are about making things clearer and easier. Many parts of the language (LINQ, extension methods, ToString(), the ?? operator) are created as conveniences. None of these are necessities, but sure are we glad that we have them. Only when we know how to use them well, we also find the true value of a feature (or not).
I'd like to add a couple of thoughts on why .NET's System.Object class definition has a ToString() method or member function, in addition to the previous postings on debugging.
Since the .NET Common Language Runtime (CLR) or Execution Runtime supports Reflection, being able to instantiate an object given the string representation of the class type seems to be essential and fundamental. And if I'm not mistaken, all reference values in the CLR are derived from System.Object, having the ToString() method in the class ensures its availability and usage through Reflection. Defining and implementing an interface along the lines of IStringable, is not mandatory or required when defining a class in .NET, and would not ensure the ability to dynamically create a new instance after querying an assembly for its supported class types.
As more advanced .NET functionality available in the 2.0, 3.0 and 3.5 runtimes, such as Generics and LINQ, are based on Reflection and dynamic instantiation, not to mention .NET's Dynamic Language Runtime (DLR) support that allow for .NET implementations of scripting languages, such as Ruby and Python, being able to identify and create an instance by a string type seems to be an essential and indispensable function to have in all class definitions.
In short, if we can't identify and name a specific class we want to instantiate, how can we create it? Relying on a ToString() method that has the base class behavior of returning the Class Type as a "human readable" string seems to make sense.
Maybe a review of the articles and books from Jeffrey Ricther and Don Box on the .NET Framework design and architecture may provide better insights on this topic as well.
In a recent project I was working I created a structure in my class to solve a problem I was having, as a colleague was looking over my shoulder he looked derisively at the structure and said "move it into a class".
I didn't have any argument for not moving it into a class other than I only need it in this class but this kind of falls down because couldn't I make it a nested class?
When is it ok to use a structure?
You should check out the value type usage guidelines: http://msdn.microsoft.com/en-us/library/y23b5415(vs.71).aspx
The article lists several important points but the few that I feel are the most valuable are the following
Is the value immutable?
Do you want the type to have value semantics?
If the answer to both questions is yes then you almost certainly want to use a Structure. Otherwise I would advise going with a class.
There are issues with using structures with a large amount of members. But I find that if I consider the two points above, rarely do I have more than the recommended number of members / size in my value types.
MSDN has a good guidelines document to cover structure usage. To summarize:
Act like primitive types.
Have an instance size under 16 bytes.
Are immutable.
Value semantics are desirable.
Otherwise, use a class.
You should always use a Class as your first choice, changing to Structure only for very specific reasons (as others have already outlined).
Depending on how much you "only need it in this class", you might be able to avoid the nested type completely by using an anonymous type; this will only work within a single method:
Public Class Foo
Public Sub Bar
Dim baz = New With { .Str = "String", .I = 314 }
End Sub
End Class
you can't (readily--there are a few things you can do with generics) move the instance baz outside of the Sub in a typesafe manner. Of course an Object can hold anything, even an instance of an anonymous type.
I think structures are great if you need copy the object or do not want it to be modified by the passed function. Since passed functions can not modify the originally passed structure instead got a new copy of it, this can be a life saver. (unless they passed as ByRef obviously) and can save you trouble of deep copy craziness in .NET or implementing pain of an ICloneSomething implementation.
But the general idea is defining a custom data structure in a more semantic way.
About moving to a class, if you are moving into a class where it'll be part of a class, generally this is good practice since your structure is 99% of the time related with one of you classes not related with a namespace.
If you are converting it to a class then you need to consider "is it defining a data strcuture" and "is it expensive?" since it's gonna be copied all over the place, "do you want to get affected by modifications done by the passers?"
The usage guidelines referenced by Marc and Rex are excellent and nicely cover cases where you aren't sure which one you would want. I will list some use cases where use of a struct is a requirement.
When you need to set the layout of the fields in memory
Interop with unmanaged code.
When you want to make Unions.
You need a fixed size buffer inlined.
You want to be able to do the equivalent of a reinterpret_cast with relative safety (so long as the struct does not contain any fields which are themselves reference types.
These are normally edge cases and (with the exception of interop) not recommended practices unless their use is necessary for the success of the project/program.
What is their use if when you call the method, it might not exist?
Does that mean that you would be able to dynamically create a method on a dynamic object?
What are the practical use of this?
You won't really be able to dynamically create the method - but you can get an implementation of IDynamicMetaObject (often by extending DynamicObject) to respond as if the method existed.
Uses:
Programming against COM objects with a weak API (e.g. office)
Calling into dynamic languages such as Ruby/Python
Potentially making "explorable" objects - imagine an XPath-like query but via a method/property calls e.g. document.RootElement.Person[5].Name["Attribute"]
No doubt many more we have yet to think of :)
First of all, you can't use it now. It's part of C#4, which will be released sometime in the future.
Basically, it's for an object, whose properties won't be known until runtime. Perhaps it comes from a COM object. Perhaps it's a "define on the fly object" as you describe (although I don't think there's a facility to create those yet or planned).
It's rather like a System.Object, except that you are allowed to call methods that the compiler doesn't know about, and that the runtime figures out how to call.
The two biggies I can think of are duck typing and the ability to use C# as a scripting language in applications, similar to javascript and Python. That last one makes me tear up a little.
Think of it as a simplified form of Reflection. Instead of this:
object value = GetSomeObject();
Method method = value.GetType().GetMethod("DoSomething");
method.Invoke(value, new object[] { 1, 2, 3 });
You get this:
IDynamicObject value = GetSomeObject();
value.DoSomething(1, 2, 3);
I see several dynamic ORM frameworks being written. Or heck write one yourself.
I agree with Jon Skeet, you might see some interesting ways of exploring objects.
Maybe with selectors like jQuery.
Calling COM and calling Dynamic Languages.
I'm looking forward to seeing if there is a way to do a Ruby-like missing_method.