ive run into a problem - these is my class structure
public interface IModel{}
public interface IGenericMapper<T> where T : IModel {...}
public class ActualModel:IModel {...}
public class ActualMapper: IGenericMapper<ActualModel> {...}
My actual code to initialse the mapper is:
IGenericMapper<IModel> mapper;
mapper= new ActualMapper();
It does not compile. I get the error
Cannot implicitly convert type 'ActualMapper' to 'IGenericMapper'. An explicit conversion exists (are you missing a cast?)
When I do cast it using
mapper= new ActualMapper() as IGenericMapper<IModel>;
the mapper does not get initialized properly (it comes back as NULL)
What am I missing - since ActualMapper()
implements IGeneric
Mapper and its type impliments `IModel' why can it not initialize mapper.
Is there another way to structure this so achieve what I need?
Thank you so much
Note the solution people have proposed gives me other compilation errors as the mapping Interface has the following members
T GetModel(busO bBusinessObject);
busO SetBusObject(T source, busO target);
apparently you cant have the generic type as an input parameter when its declared at "out"
Use a type assertion to initialize a typed, empty object using an interface in TypeScript, e.g. const emp1 = {} as MyInterface . You can access or set any properties on the object, as long as they exist on the interface and are compatible with the corresponding types.
We cannot instantiate the interface, but it can be referenced by the class object that implements it. The TypeScript compiler uses interface for type-checking (also known as "duck typing" or "structural subtyping") whether the object has a specific structure or not.
An interface type cannot be passed as a parameter. When running TypeScript code, you are really compiling it down to JavaScript and then running the JavaScript. An interface is a TypeScript compile-time construct, so at runtime, there is no such thing as an interface type to call functions on or inspect properties of.
Like abstract classes, interfaces cannot be used to create objects (in the example above, it is not possible to create an "Animal" object in the MyMainClass) Interface methods do not have a body - the body is provided by the "implement" class. On implementation of an interface, you must override all of its methods.
Pretty sure you're moving into the realm of covarience here with the Generic change;
try this:
public interface IModel{}
public interface IGenericMapper< out T> where T : IModel{}
public class ActualModel : IModel{}
public class ActualMapper : IGenericMapper<ActualModel> {}
and then:
IGenericMapper<IModel> blah = new ActualMapper();
with out the 'out T' the best you can do is:
IGenericMapper<ActualModel> blah = new ActualMapper();
This is a rabbit hole, so be careful especially if you ever try to mix the two :)
http://msdn.microsoft.com/en-us/library/ee207183.aspx
[Edit]
If you want to be able to downcast the generic T
, then it has to be out
and you cannot use it as an input. You can, however, move some of it to real time in your implementation; i.e. to a check to see if you can cast it to a model type.
interface IGenericMapper<out TModel, in TKeyOrIdent>
TModel GetModel(TKeyOrIdent bBusinessObject);
void SetModel(object model, TKeyOrIdent target);
you have to define
IGenericMapper<out T>
to support your scenario, but this applies other limitations.
Simply IGenericMapper<IModel>
!= IGenericMapper<ActualModel>
even if ActualModel : IModel
In most scenarios it makes sense to have a base interface that isn't a generic. See IList<T>
for example, it implements IList
.
You can then choose on implementation to explicitly implement interface members. See List<T>.GetEnumerator() : IEnumerable
Do not use generics under the assumption that you can eliminate casting everywhere. I've tried it C# simply doesn't have the required features for this.
I would suggest an IGenericMapper
interface as base interface for IGenericMapper<T>
then do your generic code on IGenericMapper
and finally (and at that point you already have the type) cast it back to the specific type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With