Generic object caster  
Author Message
NewbieDude





PostPosted: Visual C# General, Generic object caster Top

hi there,

i have a superclass CONTACT and subclasses COMPANY, CC, TRUST, LOCALAUTHORITY.

I want a generic method/class that takes as input a CONTACT object. This method must determine which subclass this object is (i.e. COMPANY, CC, TRUST or LOCALAUTHORITY) and then return a casted version of the same object.

e.g.:

MessageBox.Show(CastDown(myContact).idtype.tostring());

public T CastDown(CONTACT theContact)

{

if company

return (Company)theContact;


}

I can't seem to get it working Can someone help me out Do I need another class or just a method




Visual C#15  
 
 
TaylorMichaelL





PostPosted: Visual C# General, Generic object caster Top

There is already a "castdown" operator in C# known as as. It returns null if the type doesn't match what you expected it to be. If all you want is to haphazardly cast a type (not recommended) then you can also just do a typecast:

MyClass cls = (MyClass)obj; //Unsafe, but fast - use only when you are absolutely sure of the type (such as in a private method)
MyClass cls = obj as MyClass; //Safe, returns null if the obj can't be converted

Both are expressions and can therefore be used as a parameter to a method.

If you don't follow this route then you'll need to either write a method that "knows" about the various derived types or at least receives as input the type of the object to return. Neither of these cases is all that useful.

I'm wondering what you are trying to accomplish. Given that you have a base class I'd recommend that you don't worry about the underlying type unless absolutely necessary. Use virtual methods to implement the functionality without regard to underlying types. For example in the sample code you gave the cast serves no purpose because all classes implement ToString and the implementation will be appropriate for the class because it is virtual. However assuming that you really wanted to deal with some type-specific information you should use the operators mentioned earlier. Finally note that the generic method approach that you specified won't work because the return value of a function is not considered to be part of its signature. Therefore given an arbitrary object you can't create a generic method against it. You must either explicitly tell the compiler what the type is or let it use type inferencing on the arguments. Neither of these would work in your case. However you can create a more generic approach using this code:

public T CastDown<T> ( object value ) where T : class
{
return (T)value;
}

Notice that even in this case you are deferring to the operators mentioned earlier so you are really not gaining much. Also note that you must specify the type of the object to return. If you think about it for a second there probably isn't any case where you can truly treat an object as a variety of different types without picking at least a base class. Ultimately you have to assign the return value to an object and that object's type is defined in advance (even in the case of a generic method).

So, to summarize:

1) Use as to cast to a specific type when you are not sure if the object is of the specified type (the normal route)
2) Use a typecast when you are absolutely sure of the type (only normally done in private methods)
3) Use virtual methods and a base class to isolate the implementation details away from the public interface so you can work generically

Michael Taylor - 12/4/06


 
 
James Curran





PostPosted: Visual C# General, Generic object caster Top

Finally note that the generic method approach that you specified won't work because the return value of a function is not considered to be part of its signature.

That's not the reason it won't work.

The main reason it won't work is that the creation of a concrete method from the generic (and selection of which of those concrete method to call) must be done at compile time (actually JIT time), while we won't know the type we need to create until runtime.

Similarly, we have the problem of how would we declare the return type. We'd need a function like:

public T CastDown ( object value )
{
/// blah blah blah
return (COMPANY)value;

else
/// blah blah blah
return (TRUST)value;

else
/// etc

}

But one method can't have multiple different return types.

I guess the OP just had a basic misunderstanding of generics:

They are a single method which adapts at run-time, but a directive to the compiler to produce multiple methods at compile time.