Can somebody help me to get a generic object from Interface.My implementation is like the code below:
interface Itest
{
T getObject();
}
public class Test1:Itest
{
public T getObject()
{
return (T)(new logger());
}
}
You typically would need to make the interface generic, then return that specific type from the class, ie:
interface ITest<T>
{
T GetObject();
}
public class Test1 : ITest<Logger>
{
public Logger GetObject()
{
return new Logger();
}
}
Related
IServiceProvider has a single method public object? GetService (Type serviceType).
Is there a language construct to restrict the Type serviceType argument to only things that implement a certain IMarker interface (which has no methods, only serves as a marker for API discoverability).
Kind of like this (but this obviously doesn't compile):
public interface IMarker { }
public class SvcProvider : IServiceProvider {
public object? GetService(Type serviceType) where Type : IMarker {
}
}
I tried phrasing this question differently here, but got into some trouble with people understanding what I was trying to achieve.
Updated code for comments discussion:
Same snippet of dotnetfiddle: https://dotnetfiddle.net/yXNq8K
public interface IMarker {}
public class Impl1 : IMarker {}
public class Program
{
//Compiles Ok
public static T? GetServiceDefaultConstruct<T>() where T : IMarker, new() {
return new T();
}
// Doesn't compile, says that T can be a non-nullable value type.
public static T? GetServiceNull<T>() where T : IMarker {
return null;
}
// Compiles Ok
public static T? GetServiceNullExplicitConstraint<T>() where T : class,IMarker {
return null;
}
// Doesn't compile: "Can not convert Impl1 to T"
public static T? GetService<T>() where T : class,IMarker {
if (typeof(T) == typeof(Impl1))
return new Impl1();
return null;
}
}
Answering my own question:
interface IMarker { }
interface ISvcProvider {
public T? GetService<T>() where T: class, IMarker;
}
class SvcProviderImpl : ISvcProvider {
public T? GetService<T>() where T: class, IMarker {
// example of some logic for possible implementations
if (typeof(T).IsAssignableFrom(typeof(SpecificType))) {
SpecificType impl = new(); // or obtain it some other way
return impl as T;
}
return null;
}
}
I have a bunch of data fetchers which all has the almost same signature. The only thing that differs is the return type. The return type is specified as T:
I have this interface:
public interface IDataFetcher<T>
{
T FetchData(MyObject data);
}
Next I have a about 10 implementations of this interface. In de the calling code I want to do something like this:
public class FetchCommandHandler
{
private readonly IEnumerable<IDataFetcher<T>> _fetchers;
public FetchCommandHandler(IEnumerable<IDataFetcher<T>> fetchers) // this of course does not work
{
_fetchers = fetchers;
}
public MyResult Handle()
{
var myObj = new MyObject(); // get object from database
foreach(var fetcher in _fetchers)
{
var result = fetcher.FetchData(myObj);
// do something with result
}
}
}
So, in the end, what I want is not have to inject each DataFetcher<T> implementation in the constructor. I am looking for a way to retreive all the registrations of IDataFetcher<T> from StructureMap.
I am open for every other design that achieves the same result, ie, not inject each implementation in the constructor.
What we can do is introduce another interface for return type and all the types that will be returned will implement it.
Define an interface :
public interface IData
{
}
public interface IDataFetcher<T> where T : IData
{
T FetchData(MyObject data);
}
As an example a type that would be returned:
public class FooData : IData
{
}
and it's DataFetcher implementation will look like:
public class FooDataFetcher : IDataFetcher<FooData>
{
public FooData FetchData(MyObject data)
{
// logic here and return instance of FooData
}
}
Now what we can do is define the Handler class something like:
public class FetchCommandHandler
{
private readonly IEnumerable<IDataFetcher<IData>> _fetchers;
public FetchCommandHandler(IEnumerable<IDataFetcher<IData>> fetchers) // this of course does not work
{
_fetchers = fetchers;
}
public MyResult Handle()
{
var myObj = new MyObject(); // get object from database
foreach(var fetcher in _fetchers)
{
var result = fetcher.FetchData(myObj);
// do something with result
}
}
}
I got something like this:
Interface IClass
{
(something) returnClass();
}
Class Breaker: IClass
{
Public GIS.Breaker returnClass()
{
return new GIS.Breaker();
}
}
Class Conductor: IClass
{
Public GIS.Conductor returnClass()
{
return new GIS.Conductor();
}
}
Both gis.breaker and gis.conductor are build in classes imported with a dll file....
And now i dont know what to do with the interface...i need it to return a type...not a string...not a double....but a type in general
How to do it?
Breaker and Conductor must implement some common interface or you can make IClass generic.
interface IClass<T>
{
T ReturnClass();
}
class Breaker: IClass<GIS.Breaker>
{
public GIS.Breaker ReturnClass()
{
return new GIS.Breaker();
}
}
class Conductor: IClass<GIS.Conductor>
{
public GIS.Conductor ReturnClass()
{
return new GIS.Conductor();
}
}
But I think it's bad idea to combine instance builders and objects.
Coming from the Java world, programming with generics and C# is often a headache. Like this one:
interface ISomeObject { }
class SomeObjectA : ISomeObject { }
class SomeObjectB : ISomeObject { }
interface ISomething<T> where T : ISomeObject
{
T GetObject();
}
class SomethingA : ISomething<SomeObjectA>
{
public SomeObjectA GetObject() { return new SomeObjectA(); }
}
class SomethingB : ISomething<SomeObjectB>
{
public SomeObjectB GetObject() { return new SomeObjectB(); }
}
class SomeContainer
{
private ISomething<ISomeObject> Something;
public void SetSomething<T>(ISomething<T> s) where T : ISomeObject
{
Something = (ISomething<ISomeObject>)s;
}
}
class TestContainerSomething
{
static public void Test()
{
SomeContainer Container = new SomeContainer();
Container.SetSomething<SomeObjectA>(new SomethingA());
}
}
Which results into an InvalidCastException at Something = (ISomething<ISomeObject>)s;. In Java, this would work, and I could even use (if all else fails) the generics wildcard <?>. This is not possible in C#.
While this is just an example that I put together to explain the problematic, how can this exception be eliminated? The only main constraint is that SomeContainer cannot be a generic class
** Note ** : there are many questions about this, but none of them (that I could find) address a generic class member inside a non generic class.
** Update **
Inside the method SetSomething, I added these lines :
Console.WriteLine(s.GetType().IsSubclassOf(typeof(ISomething<SomeObjectA>)));
Console.WriteLine(s.GetType().ToString() + " : " + s.GetType().BaseType.ToString());
foreach (var i in s.GetType().GetInterfaces())
{
Console.WriteLine(i.ToString());
}
which to my surprise output
False
SomeThingA : System.Object
ISomething`1[SomeObjectA]
Is this why I get this exception?
Out keyword will be a fix, if your ISomething only have methods that return T
interface ISomething<out T> where T : ISomeObject
when creating a generic interface, you can specify whether there is an implicit conversion between interface instances that have different type arguments.
It is called Covariance and Contravariance
Eric Lippert have a good series of articles why we need to think about this, here interface variance is used
Here is my code, which works as expected for me
interface ISomeObject { }
class SomeObjectA : ISomeObject { }
class SomeObjectB : ISomeObject { }
interface ISomething<out T> where T : ISomeObject
{
T GetObject();
}
class SomethingA : ISomething<SomeObjectA>
{
public SomeObjectA GetObject() { return new SomeObjectA(); }
}
class SomethingB : ISomething<SomeObjectB>
{
public SomeObjectB GetObject() { return new SomeObjectB(); }
}
class SomeContainer
{
private ISomething<ISomeObject> Something;
public void SetSomething<T>(ISomething<T> s) where T : ISomeObject
{
Something = (ISomething<ISomeObject>)s;
}
}
class TestContainerSomething
{
static public void Test()
{
SomeContainer Container = new SomeContainer();
Container.SetSomething<SomeObjectA>(new SomethingA());
}
}
Sometimes it is useful to let a generic interface implement a non generic one to circumvent the missing <?>
interface ISomething
{
object GetObject();
}
interface ISomething<T> : ISomething
where T : ISomeObject
{
T GetObject();
}
public class SomeImplementation<T> : ISomething<T>
{
public T GetObject()
{
...
}
object ISomething.GetObject()
{
return this.GetObject(); // Calls non generic version
}
}
A collection can then be typed with the non generic interface
var list = new List<ISomething>();
list.Add(new SomeImplementation<string>());
list.Add(new SomeImplementation<int>());
How do I implement the function defined in the interface below? When I implemented in VS2010 like I have below. MyType gets greyed out and it doesn't recongise the type anymore? thanks!
public interface IExample
{
T GetAnything<T>();
}
public class MyType
{
//getter, setter here
}
public class Get : IExample
{
public MyType GetAnything<MyType>()
{ ^^^^^^^ ^^^^^^
MyType mt = new MyType();
^^^^^^^^^^^^^^^^^^^^^^^^^^ /* all greyed out !!*/
}
}
Make a generic interface IExample<T> and then implement it using the concrete type class Get : IExample<MyType> as in the example below.
public interface IExample<T> where T : new()
{
T GetAnything();
}
public class Get : IExample<MyType>
{
public MyType GetAnything()
{
MyType mt = new MyType();
return mt;
}
}
public class MyType
{
// ...
}
Dennis' answer looks like what you want but just in case it isn't, in order to get your code working, you can do this but I'm not sure how much value this really has...
public class Get : IExample
{
public T GetAnything<T>()
{
return default(T);
}
}
public void X()
{
var get = new Get();
var mt = get.GetAnything<MyType>();
}