How to implement both generic and non-generic version of a class? - c#

I want to implement a non-generic version of my generic class. Like this.
public class ServerSentEvent : ServerSentEvent<NoAdditionalClientInformation>
public class ServerSentEvent<ClientInfo> : IServerSentEvent
To solve this I had to make a dummy/empty class - NoAdditionalClientInformation.
Is there another way to do this without the empty class?

Usually you’d just do it the other way around:
public class ServerSentEvent : IServerSentEvent
{}
public class ServerSentEvent<ClientInfo> : ServerSentEvent
{}
That way the generic version is a more specified subtype of the non-generic one allowing you to put more information in it but to use the generic type whereever a non-generic type is expected.
If you do it like you suggested, you would need to have to specify some default type; if you can’t think of a default one, it is probably the wrong order, but in general it might depend on the case.

Related

How to add different concrete instances (which all inherit a common interface) to a collection?

I'm trying to add a few concrete instances into collection where all the concrete instances inherit from the same interface. But it doesn't compile.
// Common interface.
public interface ISearchService<in TSearchOptions> where TSearchOptions : ISearchOptions
{ .. }
// Concrete #1.
public class FooSearchService : ISearchService<FooSearchOptions>
{ .. }
// Concrete #2.
public class BaaSearchService : ISearchService<BaaSearchOptions>
{ .. }
So with the above code, both Foo and Baa both inherit from an ISearchService<ISearchOptions> but each one has defined their own specific SearchOptions type.
So then I'm trying this (which doesn't compile) :
var searchServices = new List<ISearchService<ISearchOptions>>
{
new FooSearchService(),
new BaaSearchService()
};
I've written the full code up on .NET Fiddle.
The idea is that I have a common collection of concrete instances which they all have a common base interface.
I'm pretty sure that I'm failing at this because of some *variance sillyness which I just don't understand.
I thought maybe I'm trying to do too much .. so I've tried a new .NET Fiddle with something different but that also doesn't work.
I just want a mixed bag of a common generic interface.
You should use out instead of in:
out means covariant which means that the argument can change from a class to one of its base classes. Think of method's return type (output), if you can take the result of the method as the base class, you can take any of its derived classes.
in means contravariant which means that the argument can change from a class to a class derived from it. Think of method's parameters (input), if your method can accept a derived class, you can pass to a method that wants a base class.
public interface ISearchService<out T> where T : ISearchOptions
{
}
Note: Thinking of method's input and output is just my strategy to remember when to use out and in, it's also the way delegate generic type parameters work. Basically, covariant and contravariant work in the same way for both interface and delegate.
It compiles when you change the code to this:
public interface ISearchService<out TSearchOptions> where TSearchOptions : ISearchOptions
{ }

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.

Declare C# Class That Implements a Generic Interface

Suppose I have an empty interface class IBaseInterface which is used only to "label" implementing classes as being interfaces themselves.
Is there any way to do something like this?
For example:
public class MyClass : T where T : IBaseInterface
{
}
No, you can't do that, since the compiler has to know which interface the class implements when you declare the class. You can have generic parameters to the interface, but the actual interface has to be specified.
Not like that, there isn't. I would strongly recommend using a composition pattern to try and achieve whatever you're trying. As an alternative, you might find DynamicProxy (or some other proxy solution) is what you're going for.
The type you're declaring isn't even generic. Something like this:
class MyClass<T> : T where T : IBaseInterface
could work under some circumstances (for example, if C++ templates were used instead of .Net generics), but it's simply not valid C# code.
I'm not sure what are the “labels” used for, but an interface with a property
ClassType ClassType { get; }
where
ClassType is an enum could work.

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.

Implementing a generic interface

I have a generic interface:
public interface IUnauthorizedRequestRespondable<out T> where T:class
{
T GetResponseForUnauthorizedRequest();
}
(I'm not sure why Resharper recommended T is "out", but that's not the question).
In my scenario, the object returned by GetResponseForUnauthorizedRequest is always of the type that implements the interface.
So all the interface's implementations look like:
public class SignInReturnedObject : IUnauthorizedRequestRespondable<SignInReturnedObject>
(class name and the type in brackets are always the same).
Which seems a bit awkward - isn't there a neater way to tell the compiler that the interface's method returns the type it's a part of?
Thanks.
As far as I know, there is no way to do that currently in C#.
A theoretical side-note: The feature that would allow you to do this is called self types but that's not available in C#. The idea of the feature is that you have a special type that refers to the actual type of this, so if you had a special type named self, you could probably write something like:
public interface IUnauthorizedRequestRespondable {
self GetResponseForUnauthorizedRequest();
}
...and the actual type used in place of self when you have a class SignInReturnedObject implementing the interface would be SignInReturnedObject, but unfortunatelly, that's not
available in C# :-)
If the only way you want to use that template is in that manner, I would use:
public interface IUnauthorizedRequestRespondable<T> where T:IUnauthorizedRequestRespondable<T>
{
T GetResponseForUnauthorizedRequest();
}
This has the advantage of guaranteeing it isn't used in any other way.
The class declaration won't change, but I don't see anything as awkward in this myself. Considering that you are defining a relationship between the class and itself, any more concise form might be inadvisable.
Actually, that about sums it up. That is how the syntax works.
You can see it used in .NET itself with the IEquatable inteface--you are almost always comparing an object to itself, yet you always have to provide your own class name as a template parameter.
This is simply to provide flexibility such that you can compare to anything, not necessarily yourself.
You can create a nongeneric version and just use that but I think it is more trouble than it is worth
public interface ICastUnauthorizedRequestRespondable : IUnauthorizedRequestRespondable<SignInReturnedObject>
{
}
Since T can be any class (does not have to be the class you are implementing) you need to name your class.
public class SignInReturnedObject : IUnauthorizedRequestRespondable<ANYCLASS>

Categories

Resources