2

As one who comes from a C++ background, I've come across the following situation:

Given that c# does not support typedefs, how do you programmatically relate types. That is to say in C++ I can store related types as typedefs for retrieval when used with templates. The same thing cannot be done in c# in the same way because of the lack of typedef.

For example in C++ I would:

template< typename T > class Thing : public ThingBase<T> {    public:        bool isRelated( T::Parent & otherThing )    { T::Auxillary aux( "Yes" );        return aux.isValid( otherThing ) && data.isParent( otherThing );    }    private:        T data; }; 

That would work with either of the following:

class SomeClass { public: typedef SomeClassParent Parent; typedef FooAuxillary Auxillary; bool isParent( Parent & parentObject ); }; class OtherClass { public: typedef OtherClassParent Parent; typedef BarAuxillary Auxillary; bool isParent( Parent & parentObject ); }; 

While the being able to call T::isParent on the parameter type could be achieved with a common interface interface, building the signature for Thing::isRelated seems like it would be impossible without typedefs.

So, in C# what do I do to get the related interface type for T (which is T::Interface in the C++ example)?

2
  • I'm not quite sure what you're trying to achieve here... is it generic constraints? Commented Jul 19, 2013 at 21:23
  • I need to get a type that is related to T in some way, in this case the interface for T. But since it's generic, I need to be able to retrieve that type programatically. Commented Jul 19, 2013 at 21:24

2 Answers 2

2

You need to use Generic constraints (and likely in this case) a second generic parameter as SLaks as indicated.

interface IRelated<TRelated> { bool isParent(TRelated parentObject); } class SomeClassParent {} class SomeClass : IRelated<SomeClassParent> { bool isParent(SomeClassParent parentObject) { // your logic here return true; } } class Thing<T, TParent> : ThingBase<T> where T : IRelated<TParent> {} 

To use:

var obj = new Thing<SomeClass, SomeClassParent>(); 

Here is another option. This one requires some runtime type checking (and allows isParent to be called with an object of any type), but it cleans up the syntax.

interface IRelated { bool isParent<T>(T parentObject); } class SomeClassParent {} class SomeClass : IRelated { bool isParent<T>(T parentObject) { if (parentObject is SomeClassParent) { // your logic here return true; } } } class Thing<T> : ThingBase<T> where T : IRelated {} 

To use:

var obj = new Thing<SomeClass>(); 
Sign up to request clarification or add additional context in comments.

4 Comments

Passing in all related types as parameter seems like a messy solution. Perhaps it's the only way though...
Is your Parent object the same for every type? Then you can remove the TParent generic parameter and just use IRelated<SomeBaseClass>
No, it's different for each type : / which is sort of the crux of the problem as this is a simplified example. Imagine that there's a TParent, TChild, TThis, TThat, all related to any parameter type. The collection of required dependent types is often called concepts in c++ template world.
There are a lot of options for cleaning this up. If you construct the objects using a factory, you can probably use type inference to make the syntax cleaner.
0

Use a common generic interface to relate the type:

interface IRelatedTo<TRelated> class Thing<T, TRelated> where T : IRelatedTo<TRelated> 

1 Comment

I'm having a hard time following can you clarify? what is IRelatedTo with respect to my example?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.