This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Casting an object to two interfaces at the same time, to call a generic method
I'm fairly sure you can't do this so I'm wondering if there's a workaround, but I need/want to cast an object to represent multiple interfaces for use with generic constraints. For example:
public void Foo<T>(T t) where T : IInterfaceA, IInterfaceB
{
}
If I have an object I want to say something like var t = (IInterfaceA | IInterfaceB)someObj; so I can pass t into this method.
Is there a nifty way of doing this? I'm using C# 3.5 so no dynamic available, but if it's possible with dynamic please post it anyway.
EDIT
Despite the answer below, I would say the better solution is the one that most other answers point to. (This assumes that you can redefine the multiple classes that implement both interfaces.)
Create an interface that inherits from both InterfaceA and InterfaceB, then, for all classes that implement interfaces A and B, replace those interfaces with the new one. Before:
class SomeClass : IInterfaceA, IInterfaceB { }
class AnotherClass : IInterfaceA, IInterfaceB { }
class AdditionalClass : IInterfaceA, IInterfaceB { }
After:
interface IInterfaceC : IInterfaceA, IInterfaceB { }
class SomeClass : IInterfaceC { }
class AnotherClass : IInterfaceC { }
class AdditionalClass : IInterfaceC { }
The implementation of Foo is then fairly trivial. And, again, since you don't know at compile time what type you have on hand, you may be able just to declare it as
public void Foo(IInterfaceC someObj) { }
END EDIT
You can do it using reflection, though some will say that this isn't particularly "nifty":
public class FooClass
{
public void Foo<T> (T t) where T : IInterfaceA, IInterfaceB
{
//... do your thing here
}
private static void Example(object someObj)
{
var type = someObj.GetType();
if(typeof(IInterfaceA).IsAssignableFrom(type) && typeof(IInterfaceB).IsAssignableFrom(type))
{
var genericMethod = typeof(FooClass).GetMethod("Foo");
var constructedMethod = genericMethod.MakeGenericMethod(type);
var instance = new FooClass();
var result = constructedMethod.Invoke(instance, new [] { someObj });
Assert.IsNull(result);
}
}
}
you could also do this, which could allow you to make Foo non-generic. It's also fairly ugly, so I would hide this ugliness by making it private:
private void PrivateFoo(IInterfaceA objA, IInterfaceB objB)
{
if (!ReferenceEquals(objA, objB))
throw new ArgumentException("objA and objB must refer to the same object");
//... do your thing here
}
public void Foo(object someObj)
{
PrivateFoo((IInterfaceA)someObj, (IInterfaceB)someObj);
}
public void Foo<T>(T t) where T : IInterfaceA, IInterfaceB{}
{
// T already implements IInterfaceA and IInterfaceB, just call the methods.
t.MethodFromA();
t.MethodFromB();
}
T t = (T)someObj;
This will cast the object to T, not the two interfaces... so it's up to you to make sure that'll work.
IInterfaceA tA = (IInterfaceA)someObj;
IInterfaceB tB = (IInterfaceB)someObj;
Two references to the one instance.
No, there is no way.
The only thing that comes close is to create another interface the inherits those two interfaces. But then all your classes need to implement that third interface instead of the two others, so in most circumstances, this is not practical.
Just cast it to that interface you need at that moment.
UPDATE:
The only way I can see is to create a container class that implements those interfaces:
class Container : IInterfaceA, IInterfaceB
{
private object _obj;
public Container(object obj)
{
// Check that the object really implements those two interfaces.
_obj = obj;
}
void IInterfaceA.Method1()
{
((IInterfaceA)_obj).Method1();
}
// And so on for all methods of the interfaces.
}
One possible way to do this is have inheritance of interfaces. Move the common functionality, to the parent interface, which should be used in above scenarios.
You may be able to restructure your inheritance to achieve your goal.
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
public interface IList : ICollection, IEnumerable
Note that ArrayList inerits from IList, which inherits from two interfaces already included in Arraylist.
Related
So, what exactly is a good use case for implementing an interface explicitly?
Is it only so that people using the class don't have to look at all those methods/properties in intellisense?
If you implement two interfaces, both with the same method and different implementations, then you have to implement explicitly.
public interface IDoItFast
{
void Go();
}
public interface IDoItSlow
{
void Go();
}
public class JustDoIt : IDoItFast, IDoItSlow
{
void IDoItFast.Go()
{
}
void IDoItSlow.Go()
{
}
}
It's useful to hide the non-preferred member. For instance, if you implement both IComparable<T> and IComparable it is usually nicer to hide the IComparable overload to not give people the impression that you can compare objects of different types. Similarly, some interfaces are not CLS-compliant, like IConvertible, so if you don't explicitly implement the interface, end users of languages that require CLS compliance cannot use your object. (Which would be very disastrous if the BCL implementers did not hide the IConvertible members of the primitives :))
Another interesting note is that normally using such a construct means that struct that explicitly implement an interface can only invoke them by boxing to the interface type. You can get around this by using generic constraints::
void SomeMethod<T>(T obj) where T:IConvertible
Will not box an int when you pass one to it.
Some additional reasons to implement an interface explicitly:
backwards compatibility: In case the ICloneable interface changes, implementing method class members don't have to change their method signatures.
cleaner code: there will be a compiler error if the Clone method is removed from ICloneable, however if you implement the method implicitly you can end up with unused 'orphaned' public methods
strong typing:
To illustrate supercat's story with an example, this would be my preferred sample code, implementing ICloneable explicitly allows Clone() to be strongly typed when you call it directly as a MyObject instance member:
public class MyObject : ICloneable
{
public MyObject Clone()
{
// my cloning logic;
}
object ICloneable.Clone()
{
return this.Clone();
}
}
Another useful technique is to have a function's public implementation of a method return a value which is more specific than specified in an interface.
For example, an object can implement ICloneable, but still have its publicly-visible Clone method return its own type.
Likewise, an IAutomobileFactory might have a Manufacture method which returns an Automobile, but a FordExplorerFactory, which implements IAutomobileFactory, might have its Manufacture method return a FordExplorer (which derives from Automobile). Code which knows that it has a FordExplorerFactory could use FordExplorer-specific properties on an object returned by a FordExplorerFactory without having to typecast, while code which merely knew that it had some type of IAutomobileFactory would simply deal with its return as an Automobile.
It's also useful when you have two interfaces with the same member name and signature, but want to change the behavior of it depending how it's used. (I don't recommend writing code like this):
interface Cat
{
string Name {get;}
}
interface Dog
{
string Name{get;}
}
public class Animal : Cat, Dog
{
string Cat.Name
{
get
{
return "Cat";
}
}
string Dog.Name
{
get
{
return "Dog";
}
}
}
static void Main(string[] args)
{
Animal animal = new Animal();
Cat cat = animal; //Note the use of the same instance of Animal. All we are doing is picking which interface implementation we want to use.
Dog dog = animal;
Console.WriteLine(cat.Name); //Prints Cat
Console.WriteLine(dog.Name); //Prints Dog
}
It can keep the public interface cleaner to explicitly implement an interface, i.e. your File class might implement IDisposable explicitly and provide a public method Close() which might make more sense to a consumer than Dispose().
F# only offers explicit interface implementation so you always have to cast to the particular interface to access its functionality, which makes for a very explicit (no pun intended) use of the interface.
If you have an internal interface and you don't want to implement the members on your class publicly, you would implement them explicitly. Implicit implementations are required to be public.
Another reason for explicit implementation is for maintainability.
When a class gets "busy"--yes it happens, we don't all have the luxury of refactoring other team members' code--then having an explicit implementation makes it clear that a method is in there to satisfy an interface contract.
So it improves the code's "readability".
A different example is given by System.Collections.Immutable, in which the authors opted to use the technique to preserve a familiar API for collection types while scraping away the parts of the interface that carry no meaning for their new types.
Concretely, ImmutableList<T> implements IList<T> and thus ICollection<T> (in order to allow ImmutableList<T> to be used more easily with legacy code), yet void ICollection<T>.Add(T item) makes no sense for an ImmutableList<T>: since adding an element to an immutable list must not change the existing list, ImmutableList<T> also derives from IImmutableList<T> whose IImmutableList<T> Add(T item) can be used for immutable lists.
Thus in the case of Add, the implementations in ImmutableList<T> end up looking as follows:
public ImmutableList<T> Add(T item)
{
// Create a new list with the added item
}
IImmutableList<T> IImmutableList<T>.Add(T value) => this.Add(value);
void ICollection<T>.Add(T item) => throw new NotSupportedException();
int IList.Add(object value) => throw new NotSupportedException();
In case of explicitly defined interfaces, all methods are automatically private, you can't give access modifier public to them. Suppose:
interface Iphone{
void Money();
}
interface Ipen{
void Price();
}
class Demo : Iphone, Ipen{
void Iphone.Money(){ //it is private you can't give public
Console.WriteLine("You have no money");
}
void Ipen.Price(){ //it is private you can't give public
Console.WriteLine("You have to paid 3$");
}
}
// So you have to cast to call the method
class Program
{
static void Main(string[] args)
{
Demo d = new Demo();
Iphone i1 = (Iphone)d;
i1.Money();
((Ipen)i1).Price();
Console.ReadKey();
}
}
// You can't call methods by direct class object
This is how we can create Explicit Interface:
If we have 2 interface and both the interface have the same method and a single class inherit these 2 interfaces so when we call one interface method the compiler got confused which method to be called, so we can manage this problem using Explicit Interface.
Here is one example i have given below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace oops3
{
interface I5
{
void getdata();
}
interface I6
{
void getdata();
}
class MyClass:I5,I6
{
void I5.getdata()
{
Console.WriteLine("I5 getdata called");
}
void I6.getdata()
{
Console.WriteLine("I6 getdata called");
}
static void Main(string[] args)
{
MyClass obj = new MyClass();
((I5)obj).getdata();
Console.ReadLine();
}
}
}
Here's a paraphrasing of what I want to do:
public class MyClass
{
public T GetFoo<T>() : where T : class, MyInterface
{
if (typeof(T) == typeof(Class1)
{
return new Class1() as T;
}
else if (typeof(T) == typeof(Class2))
{
return new Class2() as T;
}
else
{
return default(T);
}
}
private interface MyInterface {} // This is actually empty, it doesn't do anything except limit the types that can be passed to GetFoo()
public class Class1 : MyInterface
{
// Stuff
}
public class Class2 : MyInterface
{
// Other Stuff
}
// there are many more such classes that all inherit from MyInterface
}
So, I've got a public class with a public method. The method accepts a generic type parameter. But I want to limit the type of T that it accepts, so that's why it's using the MyInterface.
Of course that fails to compile because MyInterface is private. It throws an "Inconsistent accessibility: constraint type is less accessible than " error.
But here's why I want it to work this way:
Each of the Class1, Class2, etc are declared public, so that others can use them. But I want to restrict others from being able to declare their own such classes and pass them to the GetFoo() method. Because that will break GetFoo(), so that's why I want MyInterface to be private.
If I make MyInterface public, of course it will compile and everything will work just fine. But I need to be able to prevent others from declaring their own classes and inheriting MyInterface and passing that to GetFoo().
I want to allow callers to do this:
Class1 userFoo = GetFoo<Class1>();
I want to PREVENT callers from doing this:
Class UserClass : MyInterface {}
...
UserClass userFoo = GetFoo<UserClass>();
Edit: Thanks for all the very fast replies. Yes I know that's not the purpose of Interface's, it just seemed to make sense to me at the time. I am certainly open to a more elegant solution if one exists.
You cannot. This is fundamentally impossible. By making the interface private, the caller effectively does not know whether a class implements that interface. But by using it in a type constraint, you do require the caller to know whether a class implements that interface.
What you could do is use a common base class: even though that class has to be public, you can prevent others from deriving from it.
public class Base {
internal Base() { }
}
public interface IBase { }
public sealed class Class1 : Base, IBase {
...
}
public sealed class Class2 : Base, IBase {
...
}
public T GetFoo<T>() where T : Base, IBase {
...
}
The IBase interface is to make sure that GetFoo<Base> will be rejected. Class1 and Class2 are sealed to prevent others from deriving from those.
However, this approach can only work if Class1 and Class2 are supposed to have a common base class.
I encourage to re-think your design, though. Almost always, if your generic code has a bunch of typeof(T) == typeof(SomeConcreteClass) conditionals, that's a strong indication that you'd have been better off creating separate methods for each concrete type. But there are exceptions, and I won't rule out the possibility of your code being one of the exceptions.
It makes no sense at all to create a class that implements an interface and to try and hide the abstraction that the interface is offering to you.
OO is not about programming towards objects, what you are definitely trying to do, but about programming towards interfaces, and you are trying to hide them.
Better think of a different approach.
This code works and compiles:
public class MyClass<T> where T : class, IMyInterface
{
public T GetFoo()
{
if (typeof (T) == typeof (Class1))
{
return new Class1() as T;
}
else if (typeof (T) == typeof (Class2))
{
return new Class2() as T;
}
else
{
return default(T);
}
}
}
public interface IMyInterface {} // This is actually empty, it doesn't do anything except limit the types that can be passed to GetFoo()
public class Class1 : IMyInterface
{
// Stuff
}
public class Class2 : IMyInterface
{
// Other Stuff
}
// there are many more such classes that all inherit from MyInterface
And Main method which works fine:
static void Main(string[] args)
{
var a1 = new MyClass<Class1>();
var a2 = a1.GetFoo();
}
I'm writting a generalized method to use it in a special task at a T4 template. The method should allow me to use specialized types from a general interface. I thought about the following signatures:
interface IGreatInterface {
Object aMethodAlpha<U>(U parameter) where U : IAnInterface;
Object aMethodBeta(IAnInterface parameter)
}
public class AnInterestingClass : IAnInterface{}
When I try to implement IGreatInterface the compiler flags an error for aMethodBeta() because I've made my T4 to write that method using a subtype of IAnInterface (i.e. I want to implement that method like this: Object aMethodBeta(AnInterestingClass parameter)).
Method aMethodAlpha<U>() can be used but is not as clean as I want because my T4 has to generate some extra code. I (perhaps wrongly)
propose that an implementation of that method, which has to be done by a T4, could be
Object aMethodAlpha<AnInterestingClass>(AnInterestingClass parameter).
I'm thinking that generic methods do not support contravariant types but I'm not sure; I suppose that It's the way the compiler prevents the coder to use a specific type having a method not defined in the general type...
Does a generic method have to use the exact type when being implemented?
Is there any trick to change this behavior?
This question is quite confusing. Let me see if I can clarify it.
When I try to implement IGreatInterface the compiler flags an error for aMethodBeta() because I've made that method using a subtype of IAnInterface I want to implement that method like this: Object aMethodBeta(AnInterestingClass parameter).
That's not legal. Simplifying somewhat:
class Food {}
class Fruit : Food {}
class Meat : Food {}
interface IEater
{
void Eat(Food food);
}
class Vegetarian : IEater
{
public void Eat(Fruit fruit);
}
Class Vegetarian does not fulfill the contract of IEater. You should be able to pass any Food to Eat, but a Vegetarian only accepts Fruit. C# does not support virtual method formal parameter covariance because that is not typesafe.
Now, you might then say, how about this:
interface IFruitEater
{
void Eat(Fruit fruit);
}
class Omnivore : IFruitEater
{
public void Eat(Food food);
}
Now we have got type safety; Omnivore can be used as an IFruitEater because an Omnivore can eat fruit, as well as any other food.
Unfortunately, C# does not support virtual method formal parameter type contravariance even though doing so is in theory typesafe. Few languages do support this.
Similarly, C# does not support virtual method return type variance either.
I'm not sure if that actually answered your question or not. Can you clarify the question?
UPDATE:
What about:
interface IEater
{
void Eat<T>(T t) where T : Food;
}
class Vegetarian : IEater
{
// I only want to eat fruit!
public void Eat<Fruit>(Fruit food) { }
}
Nope, that's not legal either. The contract of IEater is that you will provide a method Eat<T> that can take any T that is a Food. You cannot partially implement the contract, any more than you could do this:
interface IAdder
{
int Add(int x, int y);
}
class Adder : IAdder
{
// I only know how to add two!
public int Add(2, int y){ ... }
}
However, you can do this:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Vegetarian : IEater<Fruit>
{
public void Eat(Fruit fruit) { }
}
That is perfectly legal. However, you cannot do:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Omnivore : IEater<Fruit>
{
public void Eat(Food food) { }
}
Because again, C# does not support virtual method formal parameter contravariance or covariance.
Note that C# does support parametric polymorphism covariance when doing so is known to be typesafe. For example, this is legal:
IEnumerable<Fruit> fruit = whatever;
IEnumerable<Food> food = fruit;
A sequence of fruit may be used as a sequence of food. Or,
IComparable<Fruit> fruitComparer = whatever;
IComparable<Apples> appleComparer = fruitComparer;
If you have something that can compare any two fruits then it can compare any two apples.
However, this kind of covariance and contravariance is only legal when all of the following are true: (1) the variance is provably typesafe, (2) the author of the type added variance annotations indicating the desired co- and contra-variances, (3) the varying type arguments involved are all reference types, (4) the generic type is either a delegate or an interface.
If you want to inherit from a generic interface, see phoog's answer. If you are talking about trying to implement an interface co-variantly, that leads to my discussion below.
Assume:
internal interface IAnInterface { }
public class SomeSubClass : IAnInterface { }
public class AnotherSubClass : IAnInterface { }
public GreatClass : IGreatInterface { ... }
The problem with trying to implement the interface with a more derived (co-variant) argument is there's no guarante when this is called through an interface that an IAnInterface passed in will be a SomeSubClass instance. This is why it's not allowed directly.
IGreatInterface x = new GreatClass();
x.aMethodBeta(new AnotherSubClass());
IF You could do covariance, this would fail because you would be expecting a SomeSubClass but would get a AnotherSubClass.
What you could do is to do explicit interface implementation:
class GreatInterface : IGreatInterface
{
// explicitly implement aMethodBeta() when called from interface reference
object IGreatInterface.aMethodBeta(IAnInterface parameter)
{
// do whatever you'd do on IAnInterface itself...
var newParam = parameter as SomeSubClass;
if (newParam != null)
{
aMethodBeta(newParam);
}
// otherwise do some other action...
}
// This version is visible from the class reference itself and has the
// sub-class parameter
public object aMethodBeta(SomeSubClass parameter)
{
// do whatever
}
}
Thus, if you did this, your interface supports the generic, the class has a more specific method, but still supports the interface. The main difference is you'd need to handle the case where an unexpected implementation of IAnInterface is passed in.
UPDATE: it sounds like you want something like this:
public interface ISomeInterface
{
void SomeMethod<A>(A someArgument);
}
public class SomeClass : ISomeInterface
{
public void SomeMethod<TA>(TA someArgument) where TA : SomeClass
{
}
}
This is not allowed, when you implement a generic method from an interface, the constraints must match.
Maybe you're looking for this:
interface IGreatInterface<in U> where U : IAnInterface
{
Object aMethodAlpha(U parameter);
}
class SomeClass : IAnInterface { /*...*/ }
class GreatClass : IGreatInterface<SomeClass>
{
public Object aMethodAlpha(SomeClass parameter) {}
}
EDIT:
Yes, you are right: if you define a generic method in an interface, you can't implement that method with a concrete method using a compatible type.
How about using a delegate (since delegates support co- and contravariance):
[example deleted because I got the variance backwards -- it doesn't work.]
I have the following interface:
internal interface IRelativeTo<T> where T : IObject
{
T getRelativeTo();
void setRelativeTo(T relativeTo);
}
and a bunch of classes that (should) implement it, such as:
public class AdminRateShift : IObject, IRelativeTo<AdminRateShift>
{
AdminRateShift getRelativeTo();
void setRelativeTo(AdminRateShift shift);
}
I realise that these three are not the same:
IRelativeTo<>
IRelativeTo<AdminRateShift>
IRelativeTo<IObject>
but nonetheless, I need a way to work with all the different classes like AdminRateShift (and FXRateShift, DetRateShift) that should all implement IRelativeTo. Let's say I have a function which returns AdminRateShift as an Object:
IRelativeTo<IObject> = getObjectThatImplementsRelativeTo(); // returns Object
By programming against the interface, I can do what I need to, but I can't actually cast the Object to IRelativeTo so I can use it.
It's a trivial example, but I hope it will clarify what I am trying to do.
If I understand the question, then the most common approach would be to declare a non-generic base-interface, i.e.
internal interface IRelativeTo
{
object getRelativeTo(); // or maybe something else non-generic
void setRelativeTo(object relativeTo);
}
internal interface IRelativeTo<T> : IRelativeTo
where T : IObject
{
new T getRelativeTo();
new void setRelativeTo(T relativeTo);
}
Another option is for you to code largely in generics... i.e. you have methods like
void DoSomething<T>() where T : IObject
{
IRelativeTo<IObject> foo = // etc
}
If the IRelativeTo<T> is an argument to DoSomething(), then usually you don't need to specify the generic type argument yourself - the compiler will infer it - i.e.
DoSomething(foo);
rather than
DoSomething<SomeType>(foo);
There are benefits to both approaches.
unfortunately inheritance doesn't work with generics. If your function expects IRelativeTo, you can make the function generic as well:
void MyFunction<T>(IRelativeTo<T> sth) where T : IObject
{}
If I remember correctly, when you use the function above you don't even need to specify the type, the compiler should figure it out based on the argument you supply.
If you want to keep a reference to one of these IRelativeTo objects inside a class or method (and you don't care what T is that), you need to make this class/method generic again.
I agree, it is a bit of pain.
If all you care about is that IRelativeTo deals with IObjects then you don't need to make it generic:
interface IRelativeTo
{
IObject getRelativeTo();
void setRelativeTo(IObject relativeTo)
}
The implementing classes may still be generic, however:
abstract class RelativeTo<T> : IRelativeTo where T : IObject
{
public virtual T getRelativeTo() {return default(T);}
public virtual void setRelativeTo(T relativeTo) {}
IObject IRelativeTo.getRelativeTo() {return this.getRelativeTo(); }
void IRelativeTo.setRelativeTo(IObject relativeTo)
{ this.setRelativeTo((T) relativeTo);
}
}
class AdminRateShift : RelativeTo<AdminRateShift>, IObject {}
Then you can do this:
IRelativeTo irt = new AdminRateShift();
IObject o = irt.getRelativeTo();
irt.setRelativeTo(o);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why cannot C# generics derive from one of the generic type parameters like they can in C++ templates?
I can do
public class MyGenericClass : DL
//but i cannot do
public class MyGenericClass <T> : T
How would i do the second? if i cannot do that, how can i do something like
public class MyGenericClass <T>
{
T obj;
//have all MyGenericClass.XYZ call obj.XYZ
}
This is not possible, because depending on what type T is, the public interface of MyGenericClass would change.
If you have lots of different classes that all expose the same interface, you could declare MyGenericClass to expose that interface, and in the implementation of all of the functions delegate the calls to obj
The specific question, why can't you do this:
public class MyGenericClass<T> : T
And you can do this:
public class MyGenericClass<T>
{
T obj;
}
The reason is that the CLR likes to be able to compile a single version of the code for MyGenericClass that will work for any reference type specified for T.
It can do this for the second case, because it can quietly replace T with object and insert appropriate casts, roughly equivalent to:
public class MyGenericClass
{
object obj;
}
But for the inheritance version, that trick doesn't work.
Also, many useful facilities would be impossible to describe through interface constraints. When you inherit from a type, you can do a lot more than just call methods on it - you can override them as well. Consider this hypothetical example:
class MyBase
{
public virtual void MyVirtual() { }
}
class MyGenericDerived<T> : T
{
public override void MyVirtual()
{
Console.WriteLine("Overridden!");
}
}
MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
What I want to do there is something like a "mix-in", where MyGenericDerived supplies definitions for virtual functions in whatever base it is applied to. But how does the compiler know that T will have a method called MyVirtual that can be overridden? I'd need to put a constraint on T. How would I express that through interfaces? It's impossible. Using interfaces to describe constraints isn't an adequate solution once you allow inheritance from type parameters. So that's another reason why it doesn't exist in the language today.
You could do something like
public interface IXyzable { void xyz(); }
public class MyGenericClass<T> : IXyzable where T : IXyzable {
T obj;
public void xyz() {
obj.xyz();
}
}
Edit: Now I understand the question
You'll need all your possible T's to implement some interface so that you know that obj.XYZ() makes sense, then you can do
public interface Ixyz
{
void XYZ();
}
public class MyGenericClass<T> : Ixyz where T:Ixyz, new()
{
T obj;
public MyGenericClass()
{
obj = new T();
}
public void XYZ()
{
obj.XYZ();
}
}
I've made MyGenericClass implement Ixyz too since it obviously does expose the right method, but maybe that's best left out since it allows
var x = new MyGenericClass<MyGenericClass<SomeClass>>();
which is unlikely to ever be a good idea.
This is pretty much duck-typing, but you could use reflection.
When you create the generic class with a reference to the obj, use reflection to try and find a method with the right signature. As long as you store a reference to the method, performance won't be too bad.
class BaseGeneric<T>
{
private T obj;
private MethodInfo mi;
private const string MethodNameOfInterest = "Xyz";
public BaseGeneric(T theObject)
{
this.obj = theObject;
Type t = obj.GetType();
mi = t.GetMethod(MethodNameOfInterest);
}
public void Xyz()
{
mi.Invoke(obj, null);
}
}
Of course, you would need to add a lot more for error checking and such, but that is the gist of what you could do. Also, don't forget to add the System.Reflection namespace to your using clause.
The .NET type system won't allow type declarations of the form you're attempting. One reason why this is disallowed should be intuitive: how would MyGenericClass<T> act when T is a sealed class (e.g. System.String)?
If you absolutely need this functionality (and you know that the type T you'll be using isn't sealed), you can generate proxies at runtime using the classes in the Reflection.Emit namespace. It may also be possible to achieve this effect using AOP tools like PostSharp.
What about this:
class BaseClass<T>
{
public T property { get; set; }
}
class GenericClass<T> : BaseClass<T>
{
}
class Program
{
static void Main(string[] args)
{
GenericClass<int> l = new GenericClass<int>();
l.property = 10;
}
}
This achieves what you want to do?