Constraints taking either types in generics
-
Hi Experts, In generics we can give constraints using the "where" clause like
public void MyGeneric <T>() where T : MyClass1 {...}
Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like
public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}
But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar
I think you cannot do that. But, on the other hand, I see no reason to do that, too. If either of the two types works for you, then they must have some common interface. So, all you have to do is to have both MyClass1 and IMyInterface implement some IGeneralInterface.
-
Hi Experts, In generics we can give constraints using the "where" clause like
public void MyGeneric <T>() where T : MyClass1 {...}
Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like
public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}
But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar
The concern is type. You need to create a common interface that both MyClass1 and IMyInterface can share. Usually MyClass1 will just implment IMyInterface negating the problem.
Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. I also do Android Programming as I find it a refreshing break from the MS. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost
-
Hi Experts, In generics we can give constraints using the "where" clause like
public void MyGeneric <T>() where T : MyClass1 {...}
Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like
public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}
But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar
You could try to simulate this with inheritance. You could do:
class MyGenericBase{ public virtual T DoSomeStuff() { ... } } class MyGeneric : MyGenericBase where T : MyClass1 { public override T DoSomeStuff { ... } } class MyGeneric1 : MyGenericBase where T : IMyInterface { public override T DoSomeStuff() { ... } }
I'm pretty sure, that you wan't be able to give derived class with the same identifier (but check it, compiler will tell you ;-) ) And question is: "Why would you want to do it?". Seems like your design isn't perfect.
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
-
I think you cannot do that. But, on the other hand, I see no reason to do that, too. If either of the two types works for you, then they must have some common interface. So, all you have to do is to have both MyClass1 and IMyInterface implement some IGeneralInterface.
I knew this would come. But my problem here is the class MyClass1 in my case is a .net class and i cannot modify it to make it implement an interface. Thanks for your time kapax5. Regards, Samar
-
I knew this would come. But my problem here is the class MyClass1 in my case is a .net class and i cannot modify it to make it implement an interface. Thanks for your time kapax5. Regards, Samar
unless the .NET class is sealed, you could derive from it and make that implement the interface of your choice. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
-
unless the .NET class is sealed, you could derive from it and make that implement the interface of your choice. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
Yes, a very good note. I am pretty sure that the author of the question understands why his provided idea is impossible. So, something must be done with inheritance, or maybe if we knew what exactly he is trying to do, we could find a workaround for the problem.
-
Hi Experts, In generics we can give constraints using the "where" clause like
public void MyGeneric <T>() where T : MyClass1 {...}
Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like
public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}
But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar
In some situations I also think it would be nice to have this possibility. But take this example:
public void MyGeneric<T>(T tValue) where T : InterfaceA | InterfaceB
{
tValue.<what>(); //<- and here is the problem - What interface do I access InterfaceA or InterfaceB?
}I hope you see where your logical mistake lies.
Greetings Covean
-
Hi Experts, In generics we can give constraints using the "where" clause like
public void MyGeneric <T>() where T : MyClass1 {...}
Now if i want the type T to be of type MyClass1 and say an interface IMyInterface then i need to do something like
public void MyGeneric <T>() where T : MyClass1, IMyInterface {...}
But I dont know (or maybe it is not possible) if we can create a generic method that can take types which inherits from either of the 2 types. i.e. if any of my other classes inherits from MyClass1 or implements IMyInterface but neither of my class has both then my generic method should work for these classes. I hope I have been clear. Please help! Thanks in advance! Regards, Samar
I'm not sure what you mean. MyClass1 doesn't need to implement IMyInterface -- as long as the provided class does and derives from MyClass1.
public class Base
{
}public class Derived : Base , System.IDisposable
{
public void
Dispose
(
)
{
}
}public class Generic<T> where T : Base , System.IDisposable
{
}var x = new Generic<Derived>() ;
-
In some situations I also think it would be nice to have this possibility. But take this example:
public void MyGeneric<T>(T tValue) where T : InterfaceA | InterfaceB
{
tValue.<what>(); //<- and here is the problem - What interface do I access InterfaceA or InterfaceB?
}I hope you see where your logical mistake lies.
Greetings Covean
That's a very bad idea, but if you need it you can simulate it by providing your own checks.
-
That's a very bad idea, but if you need it you can simulate it by providing your own checks.
What do you mean is a very bad idea, to have this 'OR' constraint? I don't think so. Take a look at this example: Lets say you want to add an extention to the values types short, int, long.
public static class ValueTypeExtention
{
// A
public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : IConvertible
{
return signedValue.ToUInt64();
}// B public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : struct { ... } // C public static ulong ToUnsignedLongUnchecked(this short signedValue) { return signedValue.ToUInt64(); } public static ulong ToUnsignedLongUnchecked(this int signedValue) { return signedValue.ToUInt64(); } public static ulong ToUnsignedLongUnchecked(this long signedValue) { return signedValue.ToUInt64(); } // D public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : short | int | long { return unchecked((ulong)signedValue); } // E public static ulong ToUnsignedLongUnchecked(this T signedValue) where T : (short | int | long) as IConvertible { return signedValue.ToUInt64(); }
}
A, B and C are versions how you could solve this problem nowadays. But lets have a deeper look: - A allows
bool bValue=false; ulong ulVal = bValue.ToUnsignedLongUnchecked();
. It allows it for every class/struct that implements IConvertible. - B needs type checking and offers ToUnsignedLongUnchecked() to every struct even BITMAPINFO. - C is the only way to solve the condition completely but needs multiple implementations. Usingwhere T : struct, IConvertible
as constraints is the best way to solve this problem with generics so far. The 'pseudo' constraint D just allows T to be one of this 3 value types. And I think E could be the best way.Greetings Covean