I have a generic class Proxy<T>, and I want to write another generic class with its type parameter being a Proxy.
I want to write:
public class MyClass<U> where U : Proxy<T>
but the compiler reports The type or namespace name T could not be found.
A solution I've found is to declare it like this:
public class MyClass<U, T> where U : Proxy<T>
but this seems clumsy as the client will have to declare two type parameters, like this:
public class SomeClass { ... }
public class SomeProxy : Proxy<SomeClass> { ... }
and then in a client somewhere:
var proxyWrapper = new MyClass<SomeProxy, SomeClass>();
How can I do this without having to have two generic types on MyClass. After all, if we know the first is SomeProxy, it should follow that the second is SomeClass.
Maybe something like this would do the job, too?
class Test<T> {
public Test(Proxy<T> proxy) { this.MyProxy = proxy; }
public Proxy<T> MyProxy { get; private set; }
}
Sorry, you just can't do this in C# without having MyClass generic on both types (unless you want to use reflection to create instances of it.)
You can have an interface IMyClass<SomeProxy> and a factory method that creates and returns an instance of MyClass<SomeProxy, SomeClass>. You may need to create the instance using Reflection.
I have a code example here of a similar situation: the end user only cares about a single type parameter, but the implementation needs to have two. In my example, I don't have to use Reflection to create the instance, but it sounds like you may need to.
What you're trying to do is possible using compile-time constructs such as C++ templates, but not run-time constructs such as C# generics.
If you want T to remain generic in Myclass, then the MyClass instance still needs to resolve all internally used generic types and you HAVE TO declare it somewhere. The way to go is the verbose way you mentioned:
public class MyClass<U, T> where U : Proxy<T>
If you don't care about the generic type T in MyClass then create interface and use it instead:
public interface IProxy { ... }
public class SomeClass { ... }
public class SomeProxy : Proxy<SomeClass>, IProxy { ... }
public class MyClass<U> where U : IProxy
and then in a client somewhere:
var proxyWrapper = new MyClass<SomeProxy>();
But do note that you cannot use type T in your interface declaration and Type U is now more general then before.
It turns out that all of the SomeProxy classes I want to deal with actually just override one method of Proxy<T> which has the signature:
T LoadInternal(Identifier id)
So, what I've done is created an internal class inside MyClass which takes a Func<Identifier, T> in its constructor. I can then pass a Func<Identifier, T> as a parameter to the constructor of MyClass and use my subclass in place of SomeProxy.
Seems a bit convoluted, but it works for me. To summarise, I now have:
public class MyClass<T>{
private SomeProxy theProxy;
public MyClass(Func<Identifier, T> loadDelegate){
theProxy = new SomeProxy(loadDelegate);
}
/* Other methods here */
class SomeProxy : Proxy<T>{
private Func<Identifier, T> m_loadInternal;
public SomeProxy(Func<Identifier, T> loadInternal){
m_loadInternal = loadInternal;
}
protected override T LoadInternal(Identifier id){
return m_loadInternal(id);
}
}
}
So, from client code, instead of writing a class which extends Proxy and then overriding LoadInternal in that class, I just create MyClass using:
var myClass = new MyClass<T>(x => CodeWhichReturnsT());
How can I do this without having to have two generic types on MyClass. After all, if we know the first is SomeProxy, it should follow that the second is SomeClass.
Although you seem to have found an answer to the main part of the question, I figured I'd offer my understanding about this part. It sounds like you wish you could do something like this:
class Proxy<T>
{
T Value { get; set; }
}
class MyClass<U> where U : Proxy<> { }
and have the compiler fill in the Proxy type parameter when you provide U. Since you have declared U as inheriting from Proxy, you must intend to use one of the methods on Proxy, that probably use the T parameter, like so:
class MyClass<U> where U : Proxy<>
{
void SomeMethod(U parameter)
{
var local = parameter.Value;
//more code here...
}
}
Now, what is the compiler supposed to infer for local here? This is the main problem I see that makes such a feature, if possible, hard to implement. If you don't want to use any methods that use the generic type of Proxy, you could instead make a non-generic base class and use that for U and sidestep the entire problem.
I am not a compiler writer, but a couple possibilities of how this could be dealt with come to mind. It could just say object (or whatever other restriction you put on the type parameter in Proxy), but that doesn't seem quite right or quite what normal generics seem to do. This would also require the CLR to allow open generic types as a constraint on the generic parameter, which I doubt it does. The other option I could see is for the type to actually have the second type parameter, and the compiler to give you syntactic sugar to make it easier.
Any way you go, this feature seems like a lot of work for a little benefit in what is probably a rare scenario, thus not likely to make the cut to get implemented.
Related
I'm not sure if this is a strange thing to do or not, or if it is some how code smell...but I was wondering if there was a way (some sort of oop pattern would be nice) to "cast" a base type to a form of its derived type. I know this makes little sense as the derived type will have additional functionality that the parent doesn't offer which is in its self not fundamentally sound. But is there some way to do this? Here is a code example to so I can better explain what I"m asking.
public class SomeBaseClass {
public string GetBaseClassName {get;set;}
public bool BooleanEvaluator {get;set;}
}
public class SomeDerivedClass : SomeBaseClass {
public void Insert(SqlConnection connection) {
//...random connection stuff
cmd.Parameters["IsItTrue"].Value = this.BooleanEvalutar;
//...
}
}
public static void Main(object[] args) {
SomeBaseClass baseClass = new SomeBaseClass();
SomeDerivedClass derClass = (SomeDerivedClass)baseClass;
derClass.Insert(new sqlConnection());
}
I know this seems goofy but is there any way to accomplish something of this sort?
Not soundly, in "managed" languages. This is downcasting, and there is no sane down way to handle it, for exactly the reason you described (subclasses provide more than base classes - where does this "more" come from?). If you really want a similar behaviour for a particular hierarchy, you could use constructors for derived types that will take the base type as a prototype.
One could build something with reflection that handled the simple cases (more specific types that have no addition state). In general, just redesign to avoid the problem.
Edit: Woops, can't write conversion operators between base/derived types. An oddity of Microsoft trying to "protect you" against yourself. Ah well, at least they're no where near as bad as Sun.
Try composition instead of inheritance!
It seems to me like you'd be better off passing an instance of SomeBaseClass to the SomeDerivedClass (which will no longer derive base class, and should be renamed as such)
public class BooleanHolder{
public bool BooleanEvaluator {get;set;}
}
public class DatabaseInserter{
BooleanHolder holder;
public DatabaseInserter(BooleanHolder holder){
this.holder = holder;
}
public void Insert(SqlConnection connection) {
...random connection stuff
cmd.Parameters["IsItTrue"].Value = holder.BooleanEvalutar;
...
}
}
public static void Main(object[] args) {
BooleanHolder h = new BooleanHolder();
DatabaseInserter derClass = new DatabaseInserter(h);
derClass.Insert(new sqlConnection);
}
Check out http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html (page 3):
Code reuse via composition Composition
provides an alternative way for Apple
to reuse Fruit's implementation of
peel(). Instead of extending Fruit,
Apple can hold a reference to a Fruit
instance and define its own peel()
method that simply invokes peel() on
the Fruit.
Personally I don't think it's worth the hassle of using Inheritance in this case. Instead just pass the base class instance in in the constructor and access it through a member variable.
private class ExtendedClass //: BaseClass - like to inherit but can't
{
public readonly BaseClass bc = null;
public ExtendedClass(BaseClass b)
{
this.bc = b;
}
public int ExtendedProperty
{
get
{
}
}
}
Downcasting makes sense, if you have an Object of derived class but it's referenced by a reference of base class type and for some reason You want it back to be referenced by a derived class type reference. In other words You can downcast to reverse the effect of previous upcasting. But You can't have an object of base class referenced by a reference of a derived class type.
I'm not saying I recommend this. But you could turn base class into JSON string and then convert it to the derived class.
SomeDerivedClass layer = JsonConvert.DeserializeObject<SomeDerivedClass>(JsonConvert.SerializeObject(BaseClassObject));
No, this is not possible. In a managed language like C#, it just won't work. The runtime won't allow it, even if the compiler lets it through.
You said yourself that this seems goofy:
SomeBaseClass class = new SomeBaseClass();
SomeDerivedClass derClass = (SomeDerivedClass)class;
So ask yourself, is class actually an instance of SomeDerivedClass? No, so the conversion makes no sense. If you need to convert SomeBaseClass to SomeDerivedClass, then you should provide some kind of conversion, either a constructor or a conversion method.
It sounds as if your class hierarchy needs some work, though. In general, it shouldn't be possible to convert a base class instance into a derived class instance. There should generally be data and/or functionality that do not apply to the base class. If the derived class functionality applies to all instances of the base class, then it should either be rolled up into the base class or pulled into a new class that is not part of the base class hierarchy.
C# language doesn't permit such operators, but you can still write them and they work:
[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Implicit(Base a) { ... }
[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Explicit(Base a) { ... }
Yes - this is a code smell, and pretty much nails down the fact that your inheritance chain is broken.
My guess (from the limited sample) is that you'd rather have DerivedClass operate on an instance of SomeBaseClass - so that "DerivedClass has a SomeBaseClass", rather than "DerivedClass is a SomeBaseClass". This is known as "favor composition over inheritance".
As others have noted, the casting you suggest is not really possible.
Would it maybe be a case where the Decorator pattern(Head First extract) can be introduced?
Have you thought about an interface that what is currently your base class and your derived class both would implement? I don't know the specifics of why you're implementing this way but it might work.
This is called downcasting and Seldaek's suggestion to use the "safe" version is sound.
Here's a pretty decent description with code samples.
This is not possible because how are you going to get the "extra" that the derived class has. How would the compiler know that you mean derivedClass1 and not derivedClass2 when you instantiate it?
I think what you are really looking for is the factory pattern or similar so you can instantiate objects without really knowing the explicit type that's being instantiate. In your example, having the "Insert" method would be an interface that instance the factory returns implements.
I dont know why no one has said this and i may have miss something but you can use the as keyword and if you need to do an if statement use if.
SomeDerivedClass derClass = class as SomeDerivedClass; //derClass is null if it isnt SomeDerivedClass
if(class is SomeDerivedClass)
;
-edit- I asked this question long ago
I've recently been in the need of extending a simple DTO with a derived type in order to put some more properties on it. I then wanted to reuse some conversion logic I had, from internal database types to the DTOs.
The way I solved it was by enforcing an empty constructor on the DTO classes, using it like this:
class InternalDbType {
public string Name { get; set; }
public DateTime Date { get; set; }
// Many more properties here...
}
class SimpleDTO {
public string Name { get; set; }
// Many more properties here...
}
class ComplexDTO : SimpleDTO {
public string Date { get; set; }
}
static class InternalDbTypeExtensions {
public static TDto ToDto<TDto>(this InternalDbType obj) where TDto : SimpleDTO, new() {
var dto = new TDto {
Name = obj.Name
}
}
}
I can then reuse the conversion logic from the simple DTO when converting to the complex one. Of course, I will have to fill in the properties of the complex type in some other way, but with many, many properties of the simple DTO, this really simplifies things IMO.
That cannot work. Go look at the help page linked by the compile error.
The best solution is to use factory methods here.
As many answers have pointed out, you can't downcast which makes total sense.
However, in your case, SomeDerivedClass doesn't have properties that will be 'missing'. So you could create an extension method like this:
public static T ToDerived<T>(this SomeBaseClass baseClass)
where T:SomeBaseClass, new()
{
return new T()
{
BooleanEvaluator = baseClass.BooleanEvaluator,
GetBaseClassName = baseClass.GetBaseClassName
};
}
So you aren't casting, just converting:
SomeBaseClass b = new SomeBaseClass();
SomeDerivedClass c = b.ToDerived<SomeDerivedClass>();
This only really works if all of the data in the base class is in the form of readable and writable properties.
C++ handles it using a constructor. C++ Typecasting. It seems like an oversight to me. Many of you have brought up the issue of what would the process do with the extra properties. I would answer, what does the compiler do when it creates the derived class when the programmer does not set the properties? I have handled this situation similar to C++. I create a constructor that takes the base class then manually set the properties in the constructor. This is definitely preferable to setting a variable in the derived class and breaking the inheritance. I would also choose it over a factory method because I think the resulting code would be cleaner looking.
Say I have two interfaces, IFeaturesA, IFeaturesB.
IFeaturesA has a set of signature methods. Let's say one is:-
public void printMe();
IFeaturesB implements IFeaturesA, and adds a new signature method, such as:-
public void printMeAlso();
Say I want to use a generic method, such as:-
public Check<E>(E passedItem)
{
}
If i passed in IFeaturesA, I want to be able to call the methods of this. If i pass in IFeaturesB, I want to be able to call the extra method, printMeAlso();
What is the best way to check for an interface type passed into a generic method and access its methods in C#? Is checking for the object type against the two interface types and then casting to the type the optimal way?
That does not fit the the generics.
Generics is a typeless reuse of the behaviour. If you need to check the type then it is not a good fit for generics. You may impose constraints but checking the actual type must not be done in the generic method..
All you are trying to abstract is the fact that you are passing an item. That is not an abstraction.
use two methods
public Check(IFeaturesA passedItem)
{
}
public Check(IFeaturesB passedItem)
{
}
add private methods to handle commonality
Don't think it's a good way to achieve what you want by defining an interface, simply define classe structure, like
public class FeaturesA
{
public virtual void printMe()
{
}
}
public class FeaturesB : FeaturesA
{
public override void printMe()
{
}
}
and after use in code, like
FeaturesA a = new FeaturesA();
FeaturesA b = FeaturesB();
public Check(A passedItem)
{
passedItem.printMe();
}
on Check(a) prints a, on Check(b) prints b
Hope this helps.
If you want to check the type of an item, use "is":
if (passedItem is IFeatureA) { }
If you want to constrain a generic to certain behaviors that can be defined by an interface or an abstract class, use "where":
public class foo<E> where E : IFeatureA
{
}
The latter case won't let you use IFeatureB, but any variable in the class of type E can use methods and properties defined in IFeatureA without checking type.
You might also want to look at type Dynamic, since it's closer to what you want to do.
I would check the type of E like
if(E.GetType().Equals(typeof(IFeaturesA)){ //call method...}
This looks like a call for another interface.
If you let both interfaces inherit from IPrintable which only contains a Print() method, and extend your Check<E>(E passedItem) with where E : IPrintable, you can call passedItem.Print().
try the following
Check(IFeaturesA f) {}
Check(IFeaturesB f){}
Check<T>(T obj) where T : IFeaturesA, IFeaturesB {}
The following code shows what I would like to do; that is, I would like to constrain anObject, so that it can be used as a parameter to various methods with use IInterfaceOne or IInterfaceTwo, where neither inherits from the other.
public interface IInterfaceOne { }
public interface IInterfaceTwo { }
public class Implementation : IInterfaceOne, IInterfaceTwo
{
}
public interface IInterfaceOneAndTwo : IInterfaceOne, IInterfaceTwo { }
public class UsingImplementation
{
IInterfaceOneAndTwo anObject = (IInterfaceOneAndTwo)(new Implementation()); //fails because Implementation doesnt acctually implement IInterfaceOneAndTwo
}
This example fails however as IInterfaceOneAndTwo is an interface in its own right, and Implementation does not implement it.
I know if I used generics I could constrain them, but I am wondering, if there is a way to do this without generics?
Is there a way to say anObject shall implement IInterfaceOne and IInterfaceTwo, without using IInterfaceOneAndTwo?
Not the way you have it currently. Only generic constraints have that ability.
You could rewrite it to use generics:
public class UsingImplementation<T>
where T : IInterface1, IInterface2, new()
{
T anObject = new T();
void SomeMethod() {
anObject.MethodFromInterface1();
}
}
You can also have generic methods, not only generic classes
public void DoSomething<T>(T value)
where T : IInterface1, IInterface2
{
value.DoInterface1Things();
value.DoInterface2Things();
}
Or
public void DoSomething<T>()
where T : IInterface1, IInterface2, new()
{
T anObject = new T();
}
You can't do that in C# without generics but there is an alternative workaround to solve the problem without generics that was not mentioned here and might fit for you. This style is often used together with the IoC principle. You could inject the same object twice. Let me change your sample quite a bit...
public interface IInterfaceOne { void Hello(); }
public interface IInterfaceTwo { void World(); }
public class Implementation : IInterfaceOne, IInterfaceTwo
{
public void Hello() { };
public void World() { };
}
public class UsingImplementation
{
private readonly IInterfaceOne one;
private readonly IInterfaceTwo two;
public UsingImplentation(IInterfaceOne one, IInterfaceTwo two)
{
this.one = one;
this.two = two;
}
// do the stuff you want to do with an IInterfaceOne using field one
public DoSomeThingWithOne() { one.Hello(); }
// do the stuff you want to do with an IInterfaceTwo using field two
public DoSomeThingWithTwo() { two.World(); }
}
Then you could wire up the things this way:
var oneAndTwo = new Implementation();
var a = new UsingImplementation(oneAndTwo, oneAndTwo);
// operates on the first param (which is the same as the second)
a.DoSomeThingWithOne();
// operates on the second param (which is the same as the first)
a.DoSomeThingWithTwo();
Have a look for IoC principle (Inversion of Control) and Dependency Injection and you'll find more solutions similiar to this one.
This way you don't need to create an extra Interface combining InterfaceOne and InterfaceTwo, two.
"Incoming" generic class parameters and generic method parameters can combine types, but there is no facility for variables or fields to represent "composite" types. Further, in order to pass an object to a parameter of a generic type which combines multiple constraints, the object must be cast to a type which in fact implements all of those constraints. This can be difficult.
For example, suppose class Foo and Bar both implement Intf1 and Intf2. One wishes to write a function AddToList<T>(thing as T) where T:Intf1,Intf2. Such a function will perfectly happily accept objects of type Foo or Bar. Suppose, however, one wishes to use such a function to add all objects to the same list (which might be a mix of Foo, Bar, and any number of other types that also happen to implement Intf1 and Intf2) and then later pass those objects to a function whose parameter is likewise constrained to implement both Intf1 and Intf2. One could cast to Foo any object which happened to be a Foo, and cast to Bar any object which happened to be a Bar, but if other types are written which also handle Intf1 and Intf2, it would be difficult to deal with them.
It is possible to solve the problem, somewhat awkwardly, without using Reflection or other such tricks. Define an interface IActUpon<Base1, Base2> with a method ActUpon<thingType>ActUpon(thingType thing) where thingType: Base1, Base2. Implementations of such a method will be able to pass parameter thing to other methods requiring generic method parameter constrained to Base1 and Base2. The biggest difficulties with such an approach are that one must write separate code for each possible number of constraints, and that in many places where one would have used a lambda expression one will instead have to write an implementation of IActUpon....
If this is desirable then there has to be a logical connection between IInterfaceOne and IInterfaceTwo and the implementing class should implement the combined interface:
class Implementation : IInterfaceOneAndTwo { ... }
If this is not possible, because it's not (all) your code then you may have to rethink the UsingImplementation. It simply doesn't fit the available surface.
I want to write the equivalent Java code of a C# code.
My C# code is as follows:
public abstract class A<T> where T : A<T>, new()
{
public static void Process()
{
Process(new T());
}
public static void Process(T t)
{
// Do Something...
}
}
public class B : A<B>
{
}
public class C : A<C>
{
}
Java equivalent of my code looks like this.
public abstract class A<T extends A<T>>
{
public static <T extends A<T>> void process()
{
process(new T()); // Error: Cannot instantiate the type T
}
public static <T extends A<T>> void process(T t)
{
// Do Something...
}
public class B extends A<B>
{
}
public class C extends A<C>
{
}
}
Here the "new()" syntax in class declaration forces derived classes to write a default constructer which makes possible to call "new T()" from base class. In other words when i am wrting the base class i am sure that the derived class will have a default constructer, so that i can instantiate a derived class object from base class.
My problem in Java is, I cannot instantiate a derived class object from super class. I get "Cannot instantiate the type T" error for "new T()" call. Is there any C# similar way in Java or should I use something like prototype pattern and cloning?
Java doesn't support reified generics, so there is no equivalent to "new T();". The way I work around this is to use reflection against a type token. The type token indicates what the generic type is.
public abstract class A<T> {
private Class<T> typeToken;
// constructor
public A() {
typeToken = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
Then use reflection to instantiate the class. It's ugly, but it gets the job done.
You can find some explanation of the difference between generics in C# and Java from this li nk - comparing java and C# generics.
Java generics are a completely compile-time construct. You cannot do anything with generic type parameters that rely in any way on runtime information. This includes:
Creating instances of generic type
parameters.
Creating arrays of generic type
parameters.
Quering the runtime class of a
generic type parameter.
Using instanceof with generic type
parameters.
You can bypass this restriction with java.lang.reflect namepsace. For example see this stackoverflow question: Genercs and Class.forName()
Also, beware of this if you are using generics.
T[] someArray = new T[];
This is one reason to prefer ArrayList to arrays. The reason for the problem lies with reifiability and type erasure.
Just use the bog standard Abstract Factory pattern. You then get the additional benefits that you are not tying down to a specific type, the implementation type need not have a specific constructor, the instance can have some parameterisation, instances can be cached, etc., etc.
For the love of god, don't use reflection.
In addition to the other comments, I would suggest not using generics. They are not needed--they get stripped out at compile time anyway--and if you do not know them well you will try to make them do things they cannot.
Once you have your class working properly, then add them back in. Your IDE will, at that point, give you a lot of useful and intelligible advice, and the generics will warn you when you use objects of the wrong class.
It does look possible to me that this class will not need generics at all when finished. (I don't know what else this class may do, and I do not understand the use of the static methods--they will never have access to an individual instance's type information.)
Actually this is not a problem in Java. The idiom is passing the class
public static <T extends A<T>> T process(Class<T> clazz)
{
T o = clazz.newInstance();
process( o );
return o;
}
X x = process(X.class); // not too verbose
I added a return value to illustrate the general case.
Kind of theoretical question. Quite long so feel free to skip if you are not in the mood for theory.
Imagine that you have two classes, one inherited from another. The base class is generic and has a method that in the closed type must return some instance of this closed type.
Like this (note ??? in text):
public class Adapter<T>
{
public virtual ??? DoSomething()
{
...
}
}
public class AdaptedString : Adapter<String>
{
public override AdaptedString DoSomething()
{
...
}
}
I can't do it because there is no way to refer to a closed type that will be derived from a generic type. (Sorry for broken language, just don't know how to express it.) There is no keyword to set in place of ??? to specify that this method will return instance of type that would be derived from this generic type.
Instead, I can use a workaround of explicitly passing the type name to the generic base. But it looks redundant.
public class Adapter<TThis,T>
{
public virtual TThis DoSomething()
{
...
}
}
public class AdaptedString : Adapter<AdaptedString,String>
{
public override AdaptedString DoSomething()
{
...
}
}
And if in the base class I need to access members of TThis instance, I have to add a constraint. This time it looks ugly - note the constraint:
public class Adapter<TThis,T>
where TThis : Adapter<TThis, T>
{
protected int _field;
...
public bool Compare( TThis obj )
{
return _field == obj._field;
}
}
public class AdaptedString : Adapter<AdaptedString,String>
{
...
}
Yes, it is all working, but it would look better if I can simply use some keyword instead of ??? in first code fragment. Something like "thistype".
How do you think will it work? Is it useful? Or maybe this is just plain stupid?
There's nothing which makes this pattern easier, and in fact the pattern isn't quite bulletproof anyway - because you can have:
class TypeA : Adapter<TypeA, string>
class TypeB : Adapter<TypeA, string> // Bug!
The second line here is entirely legal - TypeA is a valid type argument for the TThis type parameter, even though it's not what we wanted. Basically the type system doesn't let us express the concept of "T must be this type."
I disagree with those who say it's a bad or useless pattern, however. I've found it useful (if complicated) in Protocol Buffers - which would be much worse off without it. For example:
Foo foo = new Foo.Builder { Name="Jon" }.Build();
wouldn't work if Foo.Build() wasn't strongly typed to return Foo, even though the Build method is specified in IBuilder<...>.
It's worth avoiding this if you easily can simply because it gets so complicated - but I do think it's a useful pattern to know.
You'll normally just want to refer to the base class in that case:
public class Adapter<T> {
public virtual Adapter<T> DoSomething();
Trying to do what you're accomplishing violates the Liskov substitution principal.
If an inherited method in your derived class needs to return the derived type instead of the base type (known as a covariant return type), this is already supported in C#.
I too am having trouble finding an arguable use case for this (though it is an interesting idea).
Are you trying to shift around how you constrain what generic types you can use? It sounds like you want to assume some base functionality without knowing the actual type; that is what Interfaces are for. The where clause is pretty handy for those kinds of problems.
class Dictionary<K, V>
where K : IComparable, IEnumerable
where V : IMyInterface
{
public void Add(K key, V val)
{
}
}
The above example constrains K (the key) so that it must be comparable and enumerable, and V must implement whatever customer functionality you want via your own interface.