C#: Non-Generic classes using generic classes undefined - c#

I have a Generic Interface
public interface TheInterface<T> where T : IObject
I also have an object class that this interface works with
public class SomeObject : IObject
I then have a class that implements the interface
public class ClassThatWorksWithSomeObject : TheInterface<SomeObject>
This all works well enough. Later on I add a class that works with TheInterface class independent of what version of IObject he uses.
public class IDoStuffToInterface
{
public IDoStuffToInterface(TheInterface<IObject> interface)
{
//bla bla
}
}
Problem is I can't pass ClassThatWorksWithSomeObject in there, even if It inherits from the intreface and it's generic object inherits from IObject.
I guess there are some cases that it could be hurtful if it did, but I can't think of any.
Is there a way to do this better?

I don't know the detail impelmentation, you can try:
public interface TheInterface<out T> where T : IObject
if you are using C#4.0

I think what you're doing should work, but you may need to use the covariance and contravariance keywords.

You need to make you definition of TheInterface covariant so that it accepts the wider types of IObject:
public interface TheInterface<out T> where T : IObject

You should be able to do this in C#4.0 by marking the interface type as contravariant, but I think you can also get around this by making the IDoStuffInterface generic as well.
public class IDoStuffToInterface<T> where T : IObject
{
public IDoStuffToInterface(TheInterface<T> interface)
{
//bla bla
}
}
Since SomeObject qualifies for T and ClassThatWorksWithSomeObject implements TheInterface<SomeObject>, it should be acceptable as a parameter.

The other way I saw mentioned by tvanfosson was to make your IDoStuffToInterface class generic. That would work nicely as well, if (as it appears in the example) the TheInterface is being passed into the constructor and (presumably) stored in the class.
However, if it were just a function (or even a constructor) that uses the TheInterface and it isn't being stored in the class, it would probably be better to make the function itself generic and leave the class alone. For example:
public class IDoStuffToInterface
{
public void DoSomething<T>(TheInterface<T> theInterface) where T : IObject
{
//bla bla
}
}
This would allow you to do the following:
ClassThatWorksWithSomeObject myObject = new ClassThatWorksWithSomeObject();
IDoStuffToInterface actor = new IDoStuffToInterface();
actor.DoSomething(myObject);
That compiles without any problem because the compiler is able to tell by inference that you are actually calling
actor.DoSomething<SomeObject>(myObject);
Now, I think that using covariance is still probably the best option if you are in control of the interface definition. But I wanted to add this as another option for when you don't have that degree of control in your interface.

Related

What is usage of this recuring generic class?

This code is compiled in visual studio, what is it's usage
public class MyClass<T>
where T : MyClass<T>
Note where T : MyClass<T>
This is the recurring template pattern and is usually used so that a base class can refer to its real type statically. This is done in an attempt to preserve type-safety so that parameter or return values referred to in the base class track the current type in the hierarchy e.g
public class Animal<T> where T : Animal<T>
{
public abstract T GiveBirth();
}
public class Cat : Animal<Cat>
{
public override Cat GiveBirth() { return new Cat(); }
}
Without the type parameter the Animal base class method would only be able to define the return type of GiveBirth to be Animal, which may reduce type safety for the clients.
It may be acceptible if you control the entire hierarchy and can ensure that classes supply the correct type parameter, but note that it can be abused e.g.
public class Cat : Animal<Dog> { ... }
Another downside is that any clients need to take account of the generic type parameter if they want to be applied to the base class e.g.
public static void Feed<T>(Animal<T> animal) where T : Animal<T> { ... }
public static void Feed<T>(T animal) where T : Animal<T> { ... }
This is an example of the curiously recurring pattern. Eric Lippert has an excellent article on this, including why you should usually avoid it.
It might be extended like this:
public class MyChild : MyClass<MyChild>
The pattern doesn't really clue you as to why you want this generic. This is unlike most generics/constraints...e.g. if I have List<Giraffe> I can see the relationship; if I have MyGeneric<T, U> where T : IComparer<U>, I can see what T will do. With T : MyClass<T>, I really have no hints as to the relationships or usages here. Perhaps there's a...
abstract T Instance { get; }
...that you wish to have the stronger-typing of MyChild in the case of MyChild.
As an example of why this isn't so good, you could have MyOtherClass : MyClass<MyChild>, or you could have MyGrandchild : MyChild, neither of which are probably what you were trying to enforce.
For types which will only have a single layer of inheritance from an abstract base type, use of the described pattern will make it possible for the abstract base type to include methods which, when called on any member of a derived type, will return a member of that derived type. This can be a useful design feature, allowing for much cleaner caller code than would otherwise be possible. The biggest problem with this design is that because .NET has no support for covariant generic class parameters, the approach won't work with multiple layers of inheritance.
Given abstract class AnimalBase<T> where T:AnimalBase<T>, with method T Clone() and class Cat: AnimalBase<Cat>, code could say var newCat = someCat.Clone(); newCat.Meow(); rather than having to say var newCat = (Cat)(someCat.Clone()); newCat.Meow();. Unfortunately, there would be no way to have a type SiameseCat properly derives from Cat, since the only way to have mySiameseCat.Clone(); return a SiameseCat would be to have SiameseCat derive from AnimalBase<SiameseCat>, but that would prevent it from deriving from Cat.
If rather than having a class constrain to its own type, one instead defines a generic interface and constrains to that, one may avoid such difficulties. There would be no problem having SiameseCat derive from Cat while implementing IAnimal<SiameseCat>. Further, interfaces are covariant, so a type which implements IAnimal<SiameseCat> could implicitly also implement IAnimal<Cat> [if Cat was an abstract type that didn't implement the interface itself]. Every derivative of the class would have to provide its own implementations of any methods whose return value varies with the generic type parameter, but from the caller's perspective, the interface types could behave perfectly with derived classes.
It looks to be guaranteeing the type is two-dimensional (if that term makes sense here).
For example: Node<int> would end up being Node<Node<int>>.

C# Generics with 'Wildcards'

I'm looking for a way to get wildcards to work in .NET generics.
My code is as follows:
private class Rule<TSource, TSelected> where TSource : class where TSelected : class
{
// stuff in here
}
I want to be able to create a List<> of Rules where the TSource will be the same but the TSelected may be different.
You need to make a contravariant generic interface IRule<TSource, in TSelected> and make a list of that, where in addition TSelected is going to be constrained to some meaningful class. Constraining to any reference type as in your existing code will compile, but you won't be able to do anything meaningful with anything that has to do with TSelected.
At this time there is no other way to use variant generics (unless of course you go into reflection mode with List<dynamic> or something equivalent), so if this solution does not work for you you will need to redesign.
If I read your question right, I think you'd have to do this:
public interface ISelected
{
// ISelected interface
}
// A TSelected implementation
public class Implementation1: ISelected { }
// Another
public class Implementation2 : ISelected { }
// our Rule
private class Rule<TSource, TSelected> where TSource : class where TSelected ISelected
{
}
If the TSelected classes has the same super-class, you can just make a list of Rule<TSource, TSelectedSuperClass>. I believe you can use typeof (http://msdn.microsoft.com/en-us/library/58918ffs(v=vs.71).aspx) to get the exact subclass after reading the TSelected object again.
Alternatively you can make a container class to contain both and also store the exact types.
An interface could do it instead of a super class. If the Selected share implementation however, I prefer an abstract class.

Allowing implementing interface only for specific classes

Is it possible to permit only some specific classes to implement an iterface?
Let's say that I created interface IMyInterface and I want only classes which derive from UserControl to have an ability to implement my interface. Is this possible?
You cannot, but you can achieve something similar by adding a Control property to your interface, and by-convention making all the implementations return this. Doesn't solve your problem, but makes the implementer think a bit whether or not the interface really belongs there. Also allows the user of the interface to retrieve the control in a type-safe manner without casting.
interface IMyInterface
{
void Foo();
UserControl Control { get; }
}
class MyControl : UserControl, IMyInterface
{
public void Foo()
{
// TODO: Write code here
}
UserControl IMyInterface.Control
{
get { return this; }
}
}
UPDATE
There is also another solution - making a generic method. The interface itself will not be restricted, but the method operating will be. For example, the following method requires that its parameter both inherits UserControl and implements IMyInterface:
void Bar<T>(T item)
where T : UserControl, IMyInterface
{
item.Width = 120; // user control property
item.Foo(); // IMyInterface method
}
I realize this is an old post, but I had to solve exactly this problem.
Here is how you can do it:
class BaseClass { }
interface OnlyBaseClass<TSelf> where TSelf : BaseClass, OnlyBaseClass<TSelf>
{
}
class ChildClass : BaseClass, OnlyBaseClass<ChildClass> { }
class ImpostorClass : OnlyBaseClass<ImposterClass> { }
interface ImposterInterface : OnlyBaseClass<ImposterInterface > { }
Try to compile the above. You will notice that it doesn't compile (due to the two impostors, one a class, one an interface).
The constraint on TSelf can be understood as:
TSelf must: Inherit from BaseClass and implement OnlyBaseClass<TSelf>
...which only a type inheriting from BaseClass and implementing OnlyBaseClass could do.
You could be clever, and do the following:
class AdvancedImpostorClass : OnlyBaseClass<ChildClass> {}
... which will compile. You could prevent these types of impostors from ever getting through into your code by using the same constraints in any methods that accept them as arguments though, like so:
public SomeMethod<TBaseAndInterface>(TBaseAndInterface value)
where TBaseAndInterface: BaseClass, OnlyBaseClass<TBaseAndInterface>
{ }
This is all made possible through the power of F-Bound Polymorphism.
It sounds like you want something like this instead:
abstract class IMyInterface : UserControl { }
Of course IMyInterface is no longer an appropriate name, but any class that derives from IMyInterface would also derive from UserControl, which would satisfy your requirements.
This is not possible. If you can see the interface, you can implement it.
No, there is no way of restricting the implementation of an interface to specific types. Why would you need to? Why does the consumer of an abstraction care about the concrete types that implement that contract? What is your use case?
The case you describe seems to fit an "abstract method in your parent class" (here userControl) , unless the interface already exists for other purposes.
Without default body, derivated classes will have to provide a behavior.

c# generics on a method with the constraint that the type must be of "this" type

I have a C# class hierarchy with a common base type and two derived types. I want to declare an abstract method on the base class something like this :
public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass
... and I want this method to be implemented in the derived classes such that T is the type of that derived type, for each of the derived types, ie, in derived class A:
public override IEnumerable<A> GetSiblings<A>() { ... }
... and in derived class B ...
public override IEnumerable<B> GetSiblings<B>() { ... }
Put another way, each derived class must implement the method so that it returns an IEnumerable of items of the same type. Is there any way to implement this in C# ?
Well, you can hardly call a method generic if it only accepts a parameter of a single type, and your method signatures will have different return types which isn't allowed. Why don't you define an interface for all of these classes and simply return an IEnumerable<IMyClass>?
You can't do this because the return types are different. Simple as that. The reason is if you create an instance of A and stuff it into your base class(cast it) then the return type will be wrong.
You might be able to to use new instead but that might break your hierarchy.
This is not supported by the type system. It's a common enough problem, represented often as
class Animal<T> where T : Animal<T> { }
class Cat : Animal<Cat> { } // what you desire
class Dog : Animal<Cat> { } // what is possible yet not desired
But not a problem that has as yet been acted upon by the appropriate parties (be it the framework providers or C# team, not sure who).
Until it passes the critical "worth it" test as determined by costs (and opportunity costs) versus benefits, you'll have to work around it.
I found the solution. Apparently in C# 4.0, generic parameter types can be covariant, so what I've posted above will work. C# 3.5 or lower, and it doesn't work. Took a lot of Googling.

How to put an interface constraint on a generic method in C# 3.5?

I want to achieve something like this in C# 3.5:
public void Register<T>() : where T : interface {}
I can do it with class or struct, but how to do it with an interface?
If you are asking about adding a constraint to a specific interface, that's straightforward:
public void Register<T>( T data ) where T : ISomeInterface
If you are asking whether a keyword exists like class or struct to constrain the range of possible types for T, that is not available.
While you can write:
public void Register<T>( T data ) where T : class // (or struct)
you cannot write:
public void Register<T>( T data ) where T : interface
C# and the CLR don't support overall interface constraints, although you can constrain it to a particular interface (see other answers). The closest you can get is 'class' and check the type using reflection at runtime I'm afraid. Why would you want an interface constraint in the first place?
You can't demand that T is an interface, so you'd have to use reflection at runtime to assert this.
If possible, I went with a solution like this. It only works if you want several specific interfaces (e.g. those you have source access to) to be passed as a generic parameter, not any.
I let my interfaces, which came into question, inherit an empty interface IInterface.
I constrained the generic T parameter to be of IInterface
In source, it looks like this:
Any interface you want to be passed as the generic parameter:
public interface IWhatever : IInterface
{
// IWhatever specific declarations
}
IInterface:
public interface IInterface
{
// Nothing in here, keep moving
}
The class on which you want to put the type constraint:
public class WorldPieceGenerator<T> where T : IInterface
{
// Actual world piece generating code
}

Categories

Resources