Generic interfaces - c#

Here is my code
public interface ITranslator<E, R>
{
E ToEntity<T>(R record);
}
class Gens : ITranslator<string, int>
{
#region ITranslator<string,int> Members
public string ToEntity<MyOtherClass>(int record)
{
return record.ToString();
}
#endregion
}
When I compile this, I get an error Type parameter declaration must be an identifier not a type
Why is that I cannot have ToEntity<MyOtherClass> but can only have ToEntity<T> ??
Edit: what is MyOtherClass doing ? I am converting between entities(POCOs equivalent of Entity framework) and record(Object returned by the framework) for multiple tables/classes. So I would want to use this to do my class specific conversion

Your interface has a generic ToEntity<T> method that you've made non-generic in your implementation class Gens as ToEntity<MyOtherClass>. (A generic method could take any type parameter, possibly given certain constraints on T. Your Gens class is trying to provide a definition for ToEntity only for the type parameter MyOtherClass, which defeats the purpose of generics.)
In your code example, it's unclear how your Gens class is trying to use the MyOtherClass type; it's certainly not involved in the logic of ToEntity. We'd need more information to be able to guide you further.
To illustrate, here's what your current definition of the ITranslator<E, R> interface offers, in plain English:
"I provide a mechanism to translate
any record of type R into an entity
of type E, this mechanism being
dependent upon any user-specified type
T."
Your Gens class, on the other hand, the way it's currently designed, "implements" the above interface like so:
"I can translate integers to strings.
I provide the illusion of allowing
the user to specify a type to control
how this translation is performed, but
in fact there is no choice of type.
The MyOtherClass class is involved
somehow; that's all I can say."
From these two descriptions, it's clear that the Gens class is not really doing what the ITranslator<E, R> interface guarantees. Namely, it is not willing to accept a user-specified type for its ToEntity method. That's why this code won't compile for you.

You must declare a constraint on a generic type.
public string ToEntity<T>(int record) where T : MyOtherClass

That compiles OK for me in LINQpad. Maybe you have a type named E, R, or T somewhere?
Ahh I see what you're trying to do... you have MyOtherClass defined as a class somewhere yet you're trying to use it as a type argument in ToEntity. How exactly do you want MyOtherClass involved in ToEntity?

Related

Is it possible to have non-generic method return generic type?

In Java I can easily write:
public interface MyInterface<T extends Object>
and then have a method which determine the T at runtime like:
public MyInterface<?> DetermineObjectAtRuntime()
But in C# where <?> is not available and I need to call the method with type; which means I need to know the type before hand.
Is it possible to return generics type from non-generic method?
If not, how can I work out the type to call such generic method if I have an object instance with that type?
For people who are not sure what this is for - I have a set of data structures which are using different enums as field indexers. All the messages extends from a common generic interface with that enum as type variable. Now I need to work out a method which deserialize all different types of messages from a byte[] array.
In C#, which does not have type erasure, there are several ways to work around not knowing a type argument at compile-time:
Non-generic subset: If it happens to be the case that the methods of MyInterface<T> that you need don't involve T, then you can extract that portion of the interface into a base interface and return the base interface instead.
Pro: No runtime type shenanigans.
Con: Modifies the type (moving methods to a new base interface), breaking binary compatibility.
Type checking wrapper: Make a RuntimeTypeCheckedMyInterface<T> class that implements MyInterface<object> by delegating to a MyInterface<T> after type checking. Have the method return a MyInterface<object>, created by wrapping the MyInterface<whatever> inside a RuntimeTypeCheckedMyInterface.
Pro: Works with any existing interface type, without modifying it.
Con: Introduces "does T=object really mean object, or does it mean unknown type"? ambiguity.
Manual type erasure: Make a variant of MyInterface<T> that doesn't have a T like MyInterfaceOfUnknownType. Make MyInterface<T> inherit from MyInterfaceOfUnknownType. Have your method return MyInterfaceOfUnknownType.
Pro: Acts basically identical to Java, with MyInterfaceOfUnknownType = MyInterface<?>.
Con: Pollutes MyInterface<T> with non-generic methods. When the methods differ only by return type you have to disambiguate with a name change. Modifies the type (breaking source and binary compatibility).
Screw the types: Have the method return object or dynamic. Cast conditionally and appropriately.
Pro: Initially easy to do.
Con: Harder to maintain.
"But in C# where '< ? >' is not available and I need to call the method with type; which means I need to know the type before hand."
You can use dynamic instead of <T> for example:
dynamic Foo (dynamic Input) {return Input;}
The compiler determines the type at runtime.
In C#, you can have generic methods:
class Foo<X>
{
public T DoSomethingFunky<T>( ... )
{
...
}
}
But there's no way to have a wildcard type — a big fail in C#. It would be very useful in a lot of situations where you that it is a Widget<T> but you don't care about the particulars of T.
For instance, WCF throws FaultException<T>, where the various flavors of T are service specific. There's no way to catch something like FaultException<*> without simply catching the base Exception class and using reflection to inspect the caught exception to see if it's an interesting T. This prevents handling service faults in a generic way.
I believe the reason is that a concrete generic class (Widget<int>) are not really subtypes of the generic class (Widget<T>) it "inherits" from. The generic class is simply used as a template to compile a new specific class.
The one thing you could do, is have your generic template (Widget<T>) inherit from a non-generic base class (Widget) and have your method return that:
class AbstractWidget { ... }
class Widget<T> : AbstractWidget { ... }
.
.
.
public Widget GetGeneric Widget()
{
/* flavor determinated at runtime */
}
It's incumbent upon the caller to decide what to do with its Widget.
Another way is to add an extension
public static class MyExtensions
{
public static T As<T>(this object obj)
{
return (T)obj;
}
}
the above will provide you a .As() method

Generic classes - when to use and why

i understand what they are, I'm just wondering when is the best time to use them.
My first thought was - when we are building a (static) utility class which should perform certain operations on different data types.
Ergo, it is a good practice to use generic methods to avoid numerous overloads of a certain method? Please comment on this.
I have a small example class. It's just for the sake of an example.
public static class Math<T> where T : operator +, operator -
{
public static T Add(T a1, T a2)
{
return a1+a2;
}
public static T Subtract(T a1, T a2)
{
return a1 - a2;
}
}
Would this be a good usage of generic classes and methods, e.g I wish to add and subtract ints, doubles.. etc.. with the minimum amount of code ?
Why won't this compile? I've tried this as well as modifying the class signature:
public static class Math<T> where T : struct
I understand that I must specify whether the Type parameter is of reference or of value type.
I did that by specifying that T must be constrained as a value type, so why am I still getting error that the operator + and/or - cannot be applied to T (which should specifically be a value type)
No this wouldn't be a good use. Generics are to provide type-safe data structures without knowing the type. Generic constraints allow you to specify some semantics about the type, such as implementing an interface, having a default constructor, or being a class or struct.
Please see these MSDN articles:
An Introduction to C# Generics
Constraints on Type Parameters
.
It won't compile because the operator + parts are not valid constraints.
Being a value type does not infer operators such as + or -, it only infers value-type semantics (inherits object, is a value type, cannot be null, has a default constructor).
Generic Constraints
Generic constraints help the compiler give you more from your T. An unconstrained generic can only be proven to be object, so you only get access to object members on the argument.
If you state: public void Foo<T>() where T : new()
The compiler can prove that your type has a default public parameterless constructor. This is the purpose of constraints, it forces the types that can be party to the generic to conform to a contract.
There are various constraints, but as you have found there are some limitations. Interestingly, there are limitations in C# that do not exist in IL, as explored by Jon Skeet in his Unconstrained Melody library that exposes enum constraints to C#.
As written by others the operator+ isn't a valid constraint. If what you want is to make some generic math, you can use something like:
public static class Add<T>
{
public static readonly Func<T, T, T> Do;
static Add()
{
var par1 = Expression.Parameter(typeof(T));
var par2 = Expression.Parameter(typeof(T));
var add = Expression.Add(par1, par2);
Do = Expression.Lambda<Func<T, T, T>>(add, par1, par2).Compile();
}
}
public static class Math<T>
{
public static T Add(T a1, T a2)
{
return Add<T>.Do(a1, a2);
}
This will create and compile an Expression that does the operation and then cache it in a generic static class.
Sadly with this method you lose the static checking of you compiler (you could do something like:
object res = Math<object>.Add(new object(), new object());
and it would compile correctly. At runtime it would explode.)
In general you can't make a constraint asking for a specific method (static or non-static) or a specific property to be present (operators are like static methods) (with a single exception: the new() constraint that asks for a public parameterless constructor). What you can ask is for an interface to be implemented, or for a base class to be present, or for the generic parameter to be a class or a struct (where the two must be meant as "reference type" and "value type", and not simply as class and struct). Sadly there are no interfaces IAddable, ISubtractable, ... and even if you built them, int, double... wouldn't implement them, and to make it worse, in .NET you can't have generic specializations (a trick of C++ where you define a generic Math<T> and then you define special "cases" explicitly, like Math<int>, Math<double> and so on)
The obvious use case for generic classes is data structures which can then store any type of data without having to treat it all as instances of object. You probably use these all the time - IList<T>, IDictionary<K, V> etc. It lets you store things where you don't know the type when you're writing the structure while retaining type safety. The trick being that you also don't know anything about the type you're storing so you can't do much with it.
Thus generic constraints, which let you say something is a reference type or a value type, or has a parameterless constructor, or implements an interface. These come in useful when you're writing a generic class which has to do something with instances of the parameterised type. Might seem useless - why not just use an interface type as the parameter type and avoid generics altogether? Because generic constraints can force a parameter to conform to more than one interface - something you can't specify in a normal parameter type. Thus you can write a function:
public static void Frobnicate<T>(T thing)
where T : IList<int>, IDisposable
{
// ...
}
You can also stick a single base class name in there too. This is far, far more flexible than specifying concrete types. Sure you could create an interface which inherits from IList<int> and IDisposable but you can't retrofit all disposable lists of integers that might be out there to implement it.
You could also do it at runtime using reflection to inspect things, but this kind of thing is far better handled by the compiler, IMO.

Is there a syntax does a reversed type inference?

When I tried to answer the question:
Is it possible to get rid of the TClient generic type in the Service class
I found a strange usage that I've never designed something of this kind of uncompilable syntax, and following is a represent of what I encountered:
interface IGeneric<T> {
}
partial class SomeClass {
// won't compile
public static void SomeMethod<U>(Action<T> d) where T: IGeneric<U> {
}
}
And even if declared as:
class Concrete: IGeneric<object> {
}
partial class SomeClass {
public static void SomeMethod<U>(Action<IGeneric<U>> d) { // compiles
}
}
would not make the following code compile-able:
var d=default(Action<Concrete>);
SomeClass.SomeMethod(d); // won't compile
I'm not aware a syntax that works without both type parameters involved.
So I'm wondering is there a syntax does this kind of a reversed type inference? Or a workaround?
The simple answer is no. This isn't even initially about type inference - it's about type constraints. You can only add constrain a type parameter which is introduced in the same declaration. So this:
public static void SomeMethod<U>(Action<T> d) where T: IGeneric<U>
is invalid because you're trying to constrain T in terms of U, when it's U which was actually introduced in the method declaration. Indeed, T itself isn't a type parameter anywhere - but this would fail even if SomeClass were generic in T.
In many situations similar to this you can go via an extra static method in a non-generic type, to create an instance of a generic type via type inference - but the specifics are usually that you've got two type parameters and you want to specify one of them explicitly.
One important point to note is that an Action<Concrete> simply is not an Action<IGeneric<object>>. For example, Concrete may expose some extra property which an Action<Concrete> could depend on - but given an Action<IGeneric<object>> you could easily call that with a different implementation of IGeneric<object>. Your existing SomeMethod tries to sort of work around that by specific Action<U> instead of Action<IGeneric<T>> - but at that point it's relatively hard to use the action. This is rarely (in my experience) a practical approach, even when type inference works.
As soon as you change to a genuinely covariant delegate (and assuming you're using C# 4), then unless you care about U you can simply use a different signature:
using System;
interface IGeneric<T> {}
class SomeClass
{
public static void SomeMethod<T>(Func<IGeneric<T>> d) {}
}
class Concrete: IGeneric<object> {}
class Test
{
static void Main()
{
var d = default(Func<Concrete>);
// This compiles fine
SomeClass.SomeMethod(d);
}
}
The problem is that you are trying to treat an Action<T> as being covariant in T but it isn't. In fact, it's contravariant.
For example, if you had a covariant delegate, like this.
delegate T CovariantCall<out T>();
You could easily do what you're asking.
CovariantCall<IGeneric<object>> covariant = default(CovariantCall<Concrete>);
Your first example doesn't compile because you've omitted the T in the declared type parameters list for the method. It's a better idea, though, and it works because the constraint only verifies and doesn't affect parameter variance, but you would then have to explicitly specify which parameters you're looking for and can't infer it.
public static void SomeMethod<T, U>(Action<T> d) where T: IGeneric<U>
{
...
}
SomeClass.SomeMethod<Concrete, object>(default(Action<Concrete>));
There are limits to what C# type inference is capable of, and this is one of them. You can't do what you're asking without explicitly specifying the types.

Generic with multiple constraints

I'm trying to call a method with a definition similar to the following (simplified to avoid confusion):
public static void Register<T>(T value) where T : BaseClass, IInterface
This works fine so long as I have a class instance that defines both of those values. The problem occurs when I pass a `BaseClass' into a method and then try to use that instance in the above declaration. For example:
public class MyClass
{
public MyClass(BaseClass value)
{
Register(value);
}
}
I can pass and instance of a class that implements both BaseClass and IInterface into the constructor, but when I try to use that value in the Register method I get a compilation error stating:
The type 'BaseClass' cannot be used as type parameter 'T' in the generic type or method 'Register(T)'. There is no implicit reference conversion from 'BaseClass' to 'IInterface'.
If I change the type in the constructor like so:
public class MyClass
{
public MyClass(IInterface value)
{
Register(value);
}
}
I get an error stating:
The type 'IInterface' cannot be used as type parameter 'T' in the generic type or method 'Register(T)'. There is no implicit reference conversion from 'IInterface' to 'BaseClass'.
This seems like a bit of a catch-22. Is there a way that I can define the parameter to indicate that it must implement both BaseClass and IInterface?
As I was writing the question I came up with the answer and thought I would post it instead of deleting the question.
I just need to redefine the class:
public class MyClass<T> where T : BaseClass, IInterface
{
public MyClass(T value)
{
Register(value);
}
}
The solution given by Matt is an easy answer for situations where it is not necessary to store the passed-in object in a field or collection. If you need to persist the passed-in object, things get much harder. It's easy for a SomeClass<T> where T meets multiple constraints, to store items of class T and pass them as generics to routines with such constraints, but if a class has a method SomeMethod<TParam>(TParam thing) where TParam:IFoo,BaseBar, it won't have any field of type TParam. It could store thing into a field of type IFoo or BaseBar, but unless BaseBar implements IFoo, or all passed-in instances are going to derive from one particular BaseBar derivative which implements IFoo, there's no way to specify that a field's type will meet both constraints (if every instance does derive from one particular BaseBar derivative which implements IFoo, one could simply use that type as a single constraint, or for that matter not bother with generics at all—just use that as the parameter type).
There are ways of getting around these issues, either using Reflection, an interface pattern I call ISelf<T>, or some tricky nested callback interfaces. In some cases, though, it may be better to provide alternatives to methods that take double-constrained parameters (have the methods take a parameter of one constraint type, cast it to the other type, and accept the lack of compile-time safety).

Why do generic type restrictions have to be redeclared on descendant types?

In C#, given a generic type such as this:
interface IGenericType<T> where T : new()
And a descendant type, such as:
class GenericTypeImplementation<U> : IGenericType<U>
Why do we need to explicitly restrict the generic type U with all the restrictions of the parent type?
class GenericTypeImplementation<U> : IGenericType<U> where U : new()
Am I right in inferring that the issue is in the compiler computing the union of restrictions?
interface IGenericType<T> where T : new()
interface IGenericType2<T> where T : SomeOtherType
class GenericTypeImplementation<U> : IGenericType<U>, IGenericType2<U>
/* Hypothesis: Compiler can't infer U must be "SomeOtherType + new()" */
In my opinion, the compiler could be smart enough to infer the restrictions theoretically. But it shouldn't be so smart, because a too-smart compiler is sometimes dangerous. Developers always need a clear/explicit definition of everything. See this scenario:
(1) there is an interface IFoo<T> where T : new()
(2) a class Foo<T> : IFoo<T> and the new() constraint is added automatically by the compiler(brilliant!)
(3) the class Foo<T> is a very base class in the whole project, class A<T> : Foo<T>, and then class B<T> : A<T>...
(4) Now another developer can hardly realize there is such a constraint by looking into the definition of the class, he will get weird compiling errors(well that's acceptable). But what if they are invoked by reflection? Sometimes the program is correct, because the data meets the restriction by accident.
The compiler is able to to infer that U must be convertible to SomeOtherType and must have a default constructor. It will generate a compiler error for each constraint:
Error 1 The type 'U' must have a public parameterless constructor in order to use it as parameter 'T' in the generic type or method '....IGenericType<T>'
Error 2 The type 'U' must be convertible to '....SomeOtherType' in order to use it as parameter 'T' in the generic type or method '....IGenericType2<T>'
This will also happen with just one of those interfaces implemented as well. The class must successfully implement both interfaces in order to be compiled:
class GenericTypeImplementation<U> : IGenericType<U>, IGenericType2<U>
where U : SomeOtherType, new()
{...}
or as a non-generic type:
class GenericTypeImplementation : IGenericType<SomeType>, IGenericType2<SomeOtherType>
{...}
To mark a class as implementing an interface is not a way of specifying constraints on the generic type parameters of a class; it is a way of requiring that those constraints exist on a new type parameter or that they be satisfied by a supplied type.
Perhaps you could think of it this way: an interface is a constrained set of classes and a generic class is also a constrained set of classes. A generic interface is a constrained set of generic classes. When you say that a generic class implements a generic interface, you are asking the compiler, "Is this generic class strictly within the set specified by this generic interface?" You are not merely intersecting them as a further constrained set of classes.
Because a generic type restriction is on the type parameter of the defining class (U in your example), from a CLR point of view, that is a different type from the type parameter of the interface.
The type parameter of the class need not be the actual type parameter of the interface. It need not even be a simple type, as in:
class Implementation<T> : IGenericType<List<T>> { /* ... */ }
In this case, the compiler recognizes that List<T> satisfies the constraint, and so no further specification is necessary. But without such knowledge about the generic type parameter, the compiler requires you to declare it explicitly.
It is instructive to compare this to the similar but not identical behaviour of generic methods. As with classes that implement interfaces, the type restrictions must be specified with the declaration. There is one notable exception: if the implementation is explicit. In fact, the compiler will generate an error when you try to re-impose the restrictions.
For example, given an interface
interface ISomething {
void DoIt<T>() where T : new();
}
the two correct ways to implement this interface are:
class OneThing : ISomething {
public void DoIt<T>() where T : new() { }
}
class OtherThing : ISomething {
void ISomething.DoIt<T>() { }
}
Leaving out the constraint in OneThing or iserting it in OtherThing produces a compile-time error. Why do we need the constraint in the first implementation and not in the second one? I'd say for the same reason I mentioned above for type constraints on interfaces: in the first implementation, the type T has no relation to the type parameter on the interface method, so it must be made explicit for the method to match the interface method. In the second implementation, the fact that we explicitly declare the interface means that the type parameter T is the exact same one that was used in the interface.

Categories