In Java I can specify generic with wildcard "?". It is possible to create a map like this one:
Map<String, ?>.
I'm working with C# and I need a Dictionary<String, SomeInterface<?>> (where ? can be int, double, any type). Is this possible in C#?
EDIT:
Example:
interface ISomeInterface<out T>{
T Method();
void methodII();
}
class ObjectI : ISomeInterface<int>{
...
}
class ObjectII : ISomeInterface<double>{
...
}
class ObjectIII : ISomeInterface<string>{
....
}
I was trying to map this objects into Dictionary like:
Dictionary<String, ISomeInterface<?>> _objs = new Dictionary<String, ISomeInterface<?>();
_objs.Add("Object1", new ObjectI());
_objs.Add("Object2", new ObjectII());
_objs.Add("Object3", new ObjectII());
foreach(var keyVal in _objs){
Console.WriteLine(keyVal.Method());
}
Objects that implement ISomeInterface are loaded in runtime using Assembly and Activator.createInstance. In the moment of creation I don't if objects implements ISomeInterface<int> or ISomeInterface<double>.
Any help is very much appreciated.
No.
However, if you're using C# 4, you can make ISomeInterface covariant so that ISomeInterface<Anything> will be convertible to ISomeInterface<object>.
If ISomeInterface has methods that take parameters of its type parameter (as opposed to return values), this will be completely impossible, since it would then allow you to pass arbitrary objects as the parameters.
EDIT: In your specific case, the best solution is to make IMyInterface<T> inherit a separate non-generic IMyInterface interface and move all members that don't involve T to the base interface.
You can then use a Dictionary<string, IMyInterface> and you won't have any trouble.
There is the possibility to restrict your type variables to certain types:
public class Map<U, T> where T : IInterface
{
}
However, you can't do something like:
Map<string, T> map = new Map<string, T>()
For the usage you're describing, you could use a workaround, with an IDictionary<string, ISomeInterface>:
interface ISomeInterface
{
object Method();
void Method2();
}
interface ISomeInterface<T> : ISomeInterface
{
T Method();
}
class C1 : ISomeInterface<int>
{
object ISomeInterface.Method() { return Method(); }
public int Method() { return 10; }
public void Method2() { }
}
Related
In C#, suppose I have two interfaces: Foo<in P, out C> and Bar<C>. Also suppose I have two implementations of Bar<int>: BarOne and BarTwo.
I want to add a method Baz() on Bar<C> that returns something like:
public interface Bar<C> {
// other methods, some of which use C as a type
// then:
Foo<..., C> Baz ();
}
public class BarOne : Bar<int> {
// other methods...
private class FooImplOne : Foo<string, int> {
// stuff here
}
Foo<string, int> Baz() {
return new FooImplOne();
}
}
public class BarTwo : Bar<int> {
// other methods...
private class FooImplTwo : Foo<long, int> {
// stuff here
}
Foo<long, int> Baz() {
return new FooImplTwo();
}
}
But I can't say anything about the first parameter of Foo in Baz's return in the definition of the Bar interface. In java I'd use Foo<?, C> as the return type in the Bar definition - what do I do in C#?
I found a 2008 stackoverflow answer that tells me "In C# you can't do that, and need to define a base interface for Foo<P, C> that only has the generic parameter C and return that base type instead".
Is that still the case in modern, 2016 C#?
In C# you would also make the Method a generic method with a different type parameter local to that method
e.g.
public interface Bar<C> {
Foo<T, C> Baz<T>();
}
See MSDN: Generic Methods
how about
public interface Bar<T1,T2> {
Foo<T1, T2> Baz ();
}
ie pass both Foo type params in
In Java, <?> is shorthand for <? extends Object>. This means that the code that is trying to use it only knows that it is an object. The equivalent in C# would just be using <object>, so your interface would just be
Foo<object, C> Baz ();
I'm having a hard time understanding why it would be beneficial to do something like this: (Sample is a class)
static void PrintResults<T>(T result) where T : Sample
Wouldn't it be better to to just pass Sample into the method?
static void PrintResults (Sample result)
I recommend avoiding generic types where non-generic syntax works, such as the example you gave. However, there are other useful cases.
For example, specifying the return type generically:
static T Create<T>() where T: Sample, new()
{
return new T();
}
// Calling code
Sample sample = Create<Sample>();
instead of
static object Create()
{
return new Sample();
}
// Calling code
Sample sample = (Sample) Create();
You can also use templates to place multiple restrictions on a type. For example:
static T Create<T>() where T: IMyInterface, new()
{
return new T();
}
interface IMyInterface {}
class MyClass : IMyInterface { }
// Calling code.
MyClass myClass = Create<MyClass>();
This allows the generic creation of a new type that implements a specific interface and has a generic constructor. Also:
static void DoSomething<T>(T t) where T: IMyInterface1, IMyInterface2
{
t.MethodOnIMyInterface1();
t.MethodOnIMyInterface2();
}
interface IMyInterface1
{
void MethodOnIMyInterface1();
}
interface IMyInterface2
{
void MethodOnIMyInterface2();
}
class MyClass: IMyInterface1, IMyInterface2
{
// Method implementations omitted for clarity
}
// Calling code
MyClass myclass'
DoSomething(myclass); // Note that the compiler infers the type of T.
Where you can require multiple interfaces on a single parameter without (1) creating a new type that implements all these interfaces and (2) requiring parameters to be of that type.
As #dcastro points out in his/her answer, generic types can also tell the compiler to require types are the same. For example:
static void DoSomething<T>(T t1, T t2) where T: MyType
{
// ...
}
class MyType {}
class MyType1: MyType {}
class MyType2: MyType {}
// Calling code
MyType1 myType1;
MyType2 myType2;
DoSomething<MyType>(myType1, myType2);
Where the compiler requires that t1 and t2 are the same type but can be any type that inherits MyType. This is useful in automated unit testing frameworks, such as NUnit or MSTest, for generic equality and comparison checks.
Most of the answers are offering explanations of the usefulness of generics involving interfaces that don't really seem to address your actual question.
Truth is, for the example you posted, there is no benefit to using a generic method. It is actually worse because it will cause multiple implementations of the same function to be generated and ever slightly increase the code size at runtime.
In voids you could allways use an interface as a parameter to make multiple types work, so generics arent often useful here.
Only exceptions are the constraints on generics. And by that i dont mean something like
where T: IA, IB
since this could be done by an interface aswell that both implements IA and IB. This will get tiresome at some point however since you will need more and more interfaces. So lets look ath the "special constraints" class and new
public void AddNew(List<T> items) where T : new
{
items.Add(new T());
}
and class which is useful if the method mutates its parameter, which wont work for structs
static void IncA<T>(T item) where T: class, IA
{
item.A++;
}
The real power of generics is when methods have a generic return type or generic classes like List <T>. You dont want to implement a new class for every List you will need.
I have a small class that implements a dictionary that maps from the type of an interface to an implementation of that interface that extends from a base class. Unfortunately the abstract base class does not implement the interfaces, so once in the dictionary, there seems to be no way to associate the two. There is another method in this class that is dependent on storing the objects as BaseClass (in fact, most of my class is dependent on that--the getter into the dictionary is somewhat of a convenience).
private readonly Dictionary<Type, BaseClass> dictionary;
public void Add<T>(BaseClass base)
{
if (!(base is T)) // How to get rid of this check?
{
throw new ArgumentException("base does not implement " + typeof(T).Name);
}
this.dictionary.Add(typeof(T), base);
}
public T Get<T>()
{
BaseClass base;
this.dictionary.TryGetValue(typeof(T), out base);
return (T)(object)base; // How to get rid of (object) cast?
}
Are there any clever constraints I can use to remove the (base is T) check, the cast to object, or both?
Here is the class setup, for reference:
class BaseClass { }
interface IThing { }
class MyClass : BaseClass, IThing { }
dict.Add<IThing>(new MyClass());
IThing myClass = dict.Get<IThing>();
The only way to get the compile-time enforcement you're looking for would be if you have compile-type knowledge of the derived type being added.
For example, if you also specify a type parameter for the class being added then you could constrain that the class implement the interface type parameter:
public void Add<TInterface, TClass>(TClass #base)
where TClass : BaseClass, TInterface {
this.dictionary.Add(typeof(TInterface), #base);
}
So you could do this:
MyClass ok = new MyClass();
dict.Add<IThing, MyClass>(ok);
But not this:
class MyClassNotIThing : BaseClass { }
MyClassNotIThing notOk = new MyClassNotIThing();
dict.Add<IThing, MyClassNotIThing>(notOk);
Aside from that, generic constraints don't offer a means by which to constrain that a known type (i.e. BaseClass) inherit from a generic type parameter.
Here is the solution I ended up using. There are a few tricks that can make the Add() safe without the check (see the link in a comment to cokeman19's answer), but I opted not to do that as I find this code a bit cleaner.
interface IThing { }
abstract class BaseClass
{
internal T AsInterface<T> where T : class
{
return this as T;
}
}
class MyClass : BaseClass, IThing { }
class DictionaryClass
{
private readonly Dictionary<Type, BaseClass> dictionary;
public void Add<T>(BaseClass base)
{
if (base is T)
{
dictionary.Add(typeof(T), base);
}
}
public T Get<T>() where T : class
{
return dictionary[typeof(T)].AsInterface<T>();
}
}
Note that this solution does allow calls like:
myClass.AsInterface<IThingItDoesntImplement>()
but this returns null and I made the function internal to prevent strange uses anyway.
I have this issue I feel could be resolved any number of ways, but am not sure what the most efficient approach is. This same issue was idenfitied on SO at collection of different generic types, but there didn't seem to be any resolutions. I would like to resurrect this question and pick the brains of the experts!
In my case I have a contract:
public interface IServiceInvoker<TServiceContract>
{
}
There's actually an abstract class involved in this too to centralize some of the core code, but I'm not going to include that here so that the question doesn't become overly complicated.
The type TServiceContract can be any service interface. It's therefore not limited to any specific type as the implementing class will validate the service, etc. I then have this class (ServiceDAO below) to encapsulate basic use of this and other references. I'm trying to create a collection property of the IServiceInvoker type, but am having no luck... Basically what I have is:
public class ServiceDAO
{
private Dictionary<string, object> _serviceInvocationCollection = new Dictionary<string, object>();
public IEnumerable<KeyValuePair<string, object>> ServiceInvocationCollection
{
get { return _serviceInvocationCollection.AsEnumerable<KeyValuePair<string,object>>(); }
private set { _serviceInvocationCollection = value as Dictionary<string, object>; }
}
}
I would rather the collection be of the type of IServiceInvoker, but can't specify the of type TServiceContract at the class level since the collection could use any number implementing classes of IServiceInvoker... using object instead seems to be too loosely typed... any thoughts or suggestions are appreciated!
Maybe define a base interface that the generic one inherits from; then you can make the collection Dictionary<string, IServiceInvoker>.
public interface IServiceInvoker { }
public interface IServiceInvoker<TServiceContract> : IServiceInvoker
{
}
Alternatively, you could define a restriction to the TServiceContract type parameter, say IServiceContract, and use Dictionary<string, IServiceInvoker<IServiceContract>>. But then of course every service would have to inherit IServiceContract.
public interface IServiceContract { }
public interface IServiceInvoker<TServiceContract>
where TServiceContract : IServiceContract
{
}
Simple approach
Just add another interface that is not generic:
public interface IServiceInvokerUntyped
{
}
public interface IServiceInvoker<TServiceContract> : IServiceInvokerUntyped
{
}
Declare the dictionary it like this:
private Dictionary<string, IServiceInvokerUntyped> _serviceInvocationCollection = new Dictionary<string, IServiceInvokerUntyped>();
Variant approach
If your generic type parameter can be declared as covariant:
public interface IServiceInvoker<out T> : IServiceInvokerUntyped
{
}
Declare the dictionary it like this:
private Dictionary<string, IServiceInvoker<object>> _serviceInvocationCollection = new Dictionary<string, IServiceInvoker<object>>();
For contravariance, just change 'out' to 'in' and modify the dictionary declaration/initialization as appropriate.
Is there anyway to force a constraints for a generic definition to implement a "generic interface" ... that is, I want the class to support passing an interface and a generic class constraining it so that the class implements the interface. For example if I say:
MyGenericClass<IMyInterface, MyImplementation>.DoSomething();
That should be constrained so that MyImplementation implements IMyInterface
As far as I know that can be achieved by
public class Dynamic_Loader<T, S> where S: T
Now, is there anyway to also force T to be an interface?
Edit: The purpose of this was to have something like:
private static List<T> interfaceList = new List<T>();
public static List<T> InterfaceList {get { return interfaceList;}}
public static void Add(S input) { interfaceList.Add(input);}
and have the list restricted to only interfaces (since it is supposed to return implementations of certain interfaces)
Do you mean, can a constraint also be put on T like where T : interface?
If so, then no: this list pretty much covers your options.
What you have is as close as it gets, I believe.
Out of curiosity, what would be your reason for wanting to constrain T to be an interface?
Or do you mean can a constraint also be put on T for T to implement some specific interface?
If so, then yes: simply have two where clauses (e.g., where S : T where T : U).
where T: IMyOtherInterfaceForT
Example:
public class Test<T, V>
where T : V
where V : IEnumerable<int>
{
}
You could do something like this to enforce it at runtime instead of compile time.
public class Test<T> where T : class
{
public Test()
{
Type t = typeof( T );
if( !t.IsInterface )
throw new ArgumentException( "T must be an interface type" );
}
}