I am getting an object of type Company<IDesignation>. Now I want to cast it to ICompany<Manager>. Run time I know that IDesignation is nothing but "Manager" type.
Is this what you are looking for?
Company comp = new Company();
Manager mgner = new Manager(comp.getManager());
IDesignation manager = mgner;
ICompany company = (ICompany)manager;
Assuming Company is:
public class Company: ICompany, IDesignation //or something?
Using either Generic Type Casting (what u are trying to do) or simply Casting an Interface or object depends on whether you will perform this task explicitly or implicitly (maybe class has pre-defined function to cast it) and as your comment has pointed out... maybe by user or runtime matters or whether or not and/or how you need to instantiate your object so I would really need to see the class implementation in order to be able to provide something that uses type casting in the way you want to perform it.
What you need is Contravariance, i.e. your IEntityDelta generic type parameter needs to be made contravariant.
The only way to do that and for this to work is to have:
public interface IEntityDelta<in T> : IEntityDelta where T : IEntity
Note the in T in the definition.
Check out the in (Generic Modifier) (C# Reference)
Or this Understanding Covariant and Contravariant interfaces in C#
If you're not the creator of that interface and if the IEntityDelta<> is defined w/o the in modifier you're out of luck.
And just to mention that adding in/out modifiers is easier said than done. For that to compile your methods, properties etc. need to satisfy
the conditions of contravariance (or covariance in case of 'out') on that generic type (T) parameter.
And this what your classes, interfaces look like based on your info (which was terrible btw. next time you need to dedicate a bit more time
in providing minimal but complete code that makes sense):
public interface IEntityDelta<in T> : IEntityDelta
where T : IEntity
{
void MakeDelta(T entity); // this is allowed
//T Entity { get; set; } // this won't work
}
public class EntityDelta<T> : IEntityDelta<T>
where T : class, IEntity
{
public T Entity { get; set; }
public EntityDelta(T entity) => Entity = entity;
public void MakeDelta(T entity) { }
}
public interface IEntityDelta { }
public abstract class Entity : IEntity { }
public class Order : Entity { }
public interface IEntity { }
...and usage:
var order = new Order();
EntityDelta<IEntity> orderDelta = new EntityDelta<IEntity>(order);
IEntityDelta<IEntity> idelta = orderDelta;
IEntityDelta<Order> iOrderDelta = orderDelta;
Related
If I write a method accepting a parameter which derives from a BaseClass (or an interface), as far as I know there are two ways to achieve that:
void MyMethod<T>(T obj) where T : BaseClass { ... }
and
void MyMethod(BaseClass obj) { ... }
What are the differences between the two methods?
In this example there isn't a big difference between the two, you can access the same members inside the method and you can call it with the same derived classes. There is a runtime difference as a generic method is compiled for each type it is invoked with.
Where generics come in useful would be if you would return a value depending on T
With generics you could do the following
T MyMethod<T>(T obj) where T : BaseClass { ... }
MyMethod(derivedInstance).derivedProperty
Without this would be an error:
BaseClass MyMethod(BaseClass obj) { ... }
MyMethod(derivedInstance).derivedProperty // error
Note Although you mention constraining to a base class, it is worth mentioning that if you constrain not to a class, but to an interface, extra boxing will occur if the implementation is by a struct in the non generic version, this can have severe performance implications.
When T is constrained to a base class, there is not really much difference apart from what has already been stated.
When T is constrained to an interface, the difference can be huge:
int FrobNonGeneric(IFrobbable frob) { //... }
int Frob<T>(T frob) where T: IFrobbable { //... }
struct Frob: IFrobbable { ... }
FrobNonGeneric(new Frob()); //boxing!
Frob(new Frob()); //no boxing
Definitely the example you quoted does not make much difference other than run time execution performance as mentioned in other answers.
Leaving aside generic collections benefits (performance improvement by avoiding boxing/unboxing for example) which we all aware of and we use frequently - Generics also works great from a consumer perspective. For example, the below code snippet is self explanatory to visualize API usage flexibility from a consumer perspective :
interface IEntity
{
int Id {get;set;}
}
class Student : IEntity
{
int Id {get;set;}
string SubjectOpted {get;set;}
}
class Employee : IEntity
{
int Id {get;set;}
string DepartmentName{get;set;}
}
interface INonGenericRepository
{
IEntity Get(int id)
}
interface IGenericRepository<T> where T:Entity
{
T Get(int id)
}
class NonGenericRepository : IRepository
{
public IEntity Get(int id) {/*implementation goes here */
}
class GenericRepository<T> : IRepository<T>
{
public T Get(int id) {/*implementation goes here */
}
Class NonGenericStudentConsumer
{
IEntity student = new NonGenericFRepository().Get(5);
var Id = student.Id
var subject = student.SubjectOpted /*does not work, you need to cast */
}
Class GenericStudentConsumer
{
var student = new GenericFRepository<Student>().Get(5);
var Id = student.Id
var subject = student.SubjectOpted /*works perfect and clean */
}
A couple of other use cases promoting flexibility while using generics along with constraints are :
Lets say I want to ensure parameter passed to method implements IAdd and IMultiply and I have class which implements both IAdd,IMulitply like :
public class BusinessOpeartion<T> where T : IAdd, IMultiply{
void SomeBusinessOpeartion(T obj) { /*implementation */}
}
If I need to go via non generic approach, I am forced to create redundant dummy interface like :
interface IDummy : IAdd, IMultiply
public class BusinessOpeartion{
void SomeBusinessOpeartion(IDummy obj) { /*implementation */}
}
Isn't the former approach cleaner?
Also one more small thing just popped up while typing answer. In case you need to, how would you get new instance for parameter type inside method:
you cannot do
IDummy dummy = new IDummy(); /*illegal*/
But with generic you could have; T temp = new T(); provided there is constraint of new()
Also what if you need a default value for parameter type?
you cannot do
var default = default(IDummy); /*illegal*/
But with generic you could have; var default = default(T)
As was said, it matters only once you get a return value. Consider these cases:
BaseClass MyMethod(BaseClass)
DervivedClass temp = new DervivedClass();
//Error. My Method always returns a BaseClass. No implicit casting available
temp = MyMethod(temp);
Compare it to this:
T MyMethod<T>(T) where T : BaseClass
DervivedClass temp = new DerivedClass();
temp = MyMethod<DerivedClass>(temp);
Strong Typification is one of the best friends you have in .NET. Embrace it. Never try to avoid it. The opposite would be cases like we have in PHP and JavaScript: http://www.sandraandwoo.com/2015/12/24/0747-melodys-guide-to-programming-languages/
In the examples included in your question, there isn't much difference between the generic and the non-generic version. But here are some other examples of method signatures that can't be expressed without generics:
T MyMethod<T>(T obj) where T : BaseClass { ... }
void MyMethod<T>(T obj1, T obj2) where T : BaseClass { ... }
void MyMethod<T>(T obj, List<T> list) where T : BaseClass { ... }
I have an interface IRecordBuilder and an abstract class Query with a field protected IRecordBuilder recordBuilder and a method public abstract IList<IRecords> GetRecordsFromResults();.
In Query child classes constructors, I specify a recordBuilder concrete type depending on which child class I am in, for exemple :
recordBuilder = new RecordsPerMonthBuilder(); //RecordsPerMonthBuilder implements IRecordBuilder
I would like to use my recordBuilder field in the implementations of the abstract method above, but the properties in the implementations of IRecordBuilder remains unknown at compile time and i can't use them.
Besides transfering recordBuilder from mother class to each child classes and instantiate it there with the proper type, is there a way to make the polymorphism work here ?
Here are the explanations in code format :
public interface IRecordBuilder
{
IRecords BuildRecord();
}
public class RecordsPerMonthBuilder : IRecordBuilder
{
public IRecords BuildRecord()
{
if(Foo != null) return new FooRecord(Foo); // class FooRecord : IRecord
return null;
}
public string Foo {get; set;}
}
public abstract class Query
{
protected IRecordBuilder recordBuilder;
public abstract IList<IRecords> GetRecordsFromResults();
}
public sealed class ConcreteQuery: Query
{
public ConcreteQuery()
{
RecordBuilder = new RecordsPerMonthBuilder();
}
public override IList<IRecords> GetRecordsFromResults()
{
var recordsList = new List<IRecords>();
recordBuilder.foo = "foo"; // IRecordBuilder does not contain a definition for foo
recordsList.Add(RecordBuilder.BuildRecord());
return recordsList;
}
}
I see three possible solutions for this:
Option 1: In your child class, cast the builder to the concrete type (since the child class created it, it knows the concrete type). If you do that, you might want to make the recordBuilder field readonly and pass it to the base constructor to ensure at compile time that its type cannot be changed.
Option 2: In your child class, keep an additional "strongly typed" reference to the record builder. (In fact, why do you even need the "interface typed" reference at all?)
public sealed class ConcreteQuery: Query
{
private RecordsPerMonthBuilder myBuilder;
public ConcreteQuery()
{
myBuilder = new RecordsPerMonthBuilder();
RecordBuilder = myBuilder;
}
public override IList<IRecords> GetRecordsFromResults()
{
var recordsList = new List<IRecords>();
myBuilder.foo = "foo";
recordsList.Add(myBuilder.BuildRecord());
return recordsList;
}
}
Option 3: Make your base class generic:
public abstract class Query<TBuilder> where TBuilder : IRecordBuilder
{
protected TBuilder RecordBuilder;
public abstract IList<IRecords> GetRecordsFromResults();
}
public sealed class ConcreteQuery : Query<RecordsPerMonthBuilder>
{
...
}
One area of confusion is that your Query class depends explicitly on one implementation of IRecordBuilder, RecordsPerMonthBuilder. The interface IRecordBuilder doesn't have a Foo property, but Query depends on the Foo property. Query is hard-coded to only use RecordsPerMonthBuilder.
It's difficult to see the intent. One way to clear it up is to make sure that any interaction between Query and an implementation of IRecordBuilder is defined in IRecordBuilder. Query should depend on the interface and shouldn't call any properties or methods that aren't in that interface.
If only one implementation of IRecordBuilder requires a Foo, then that value shouldn't be coming from your Query class because Query doesn't know that IRecordBuilder needs a Foo. It shouldn't know what an implementation of IRecordBuilder needs, only what it does.
Here's a way to move it around. You'll see this pattern a lot.
public abstract class Query
{
protected IRecordBuilder RecordBuilder { get; private set; }
protected Query(IRecordBuilder recordBuilder)
{
RecordBuilder = recordBuilder;
}
public abstract IList<IRecords> GetRecordsFromResults();
}
Now it will never know what the implementation of IRecordBuilder is. That's good. It's now impossible for it to depend on anything that's not in the IRecordBuilder interface. Now Query depends on an abstraction, applying the Dependency Inversion principle.
What about RecordsPerMonthBuilder? It depends on a value, Foo. Will every implementation of IRecordBuilder need that? If so you could add it to the interface:
IRecords BuildRecord(string foo);
But if only one implementation needs that value then it shouldn't come from Query, because Query shouldn't know the difference between one IRecordBuilder and another. I can't answer that more specifically because I don't know what Foo is.
Another suggestion: If the inheritance between Query and ConcreteQuery gives you any grief, just don't use inheritance. Sometimes trying to use inheritance creates complications and doesn't give us any benefit in return.
I am trying to design an interface, so that it has a generic type of id and a generic method that returns the type of the class that implements this interface. For example:
public interface IEntity <IDType, MethodReturnType>
{
IDType ID {get; set;}
MethodReturnType Get();
}
public class Model : IEntity<int, Model>
{
int ID {get; set; }
Model Get() { // do something }
}
My question is, it seems silly to put in Model as the second type parameter of IEntity, because I am already in a Model's class, it should be some intelligence way to figure out what type it is (although using generic type requires it to be determined before compile time).
Is it any other solution that can help me to get rid of the Model type while retain the Get method definition in the interface?
In this context, there are two typical ways to go about designing your classes and interfaces. I'll stray slightly from your exact example to try to make the answer more general.
Which option to choose really depends on how you want your classes and interfaces to be used.
Option 1
Make your interface generic, so that the interface members have knowledge of the exact type.
public interface IEntity<TDescription>
{
TDescription Get();
}
public class MyModel : IEntity<MyDescription>
{
MyDescription Get() { ... }
}
public class MyDescription { ... }
This means that when you use your interface IEntity<TDescription> you need to know TDescription at the time of use. The benefit is that you get more compile-time type checking.
Option 2
Do not make your interface generic and instead have your interface members use interfaces as well.
public interface IEntity
{
IDescription Get();
}
public interface IDescription { ... }
public class MyModel : IEntity
{
MyDescription Get() { ... }
IDescription IEntity.Get() { return this.Get(); }
}
public class MyDescription : IDescription { ... }
This is more flexible, but it also means less compile-time type checking.
You can determine the inherited class type with this.GetType() but that will not allow you to create generic functions/parameters/etc as you are doing.
So to your answer, no, you can't unless you will not use that type in any way (you can still get the base type of the class and use it but cannot set it as return type/param type/etc).
I've read an excellent article on MSDN regarding Generics in C#.
The question that popped in my head was - why should i be using generic constraints?
For example, if I use code like this:
public class MyClass<T> where T : ISomething
{
}
can't I switch ALL references of T in this class with ISomething?
What's the benefit of using this approach?
You ask, "can't I switch ALL references of T in this class with ISomething?" So I think you mean to compare:
public class MyClass<T> where T : ISomething
{
public T MyProperty { get; set; }
}
With:
public class MyClass
{
public ISomething MyProperty { get; set; }
}
In the second example, MyProperty is only guaranteed to be an instance of ISomething. In the first example, MyProperty is whatever T is, even if that is a specific subtype of ISomething. Consider a concrete implementation of ISomething:
public class MySomething : ISomething
{
public string MyOtherProperty { get; set; }
}
Now, if we use the first, generic, example, we could have:
MyClass<MySomething> myClass = new MyClass<MySomething>();
Console.WriteLine(myClass.MyProperty.MyOtherProperty);
On the other hand, if we used the second example, we wouldn't be able to access MyOtherProperty since it's only known to be an ISomething:
MyClass myClass = new MyClass();
Console.WriteLine(myClass.MyProperty.MyOtherProperty); // Won't compile, no property "MyOtherProperty"
On a different note, the reason these type constraints are useful is that you can refer to MyProperty (type T) and access members of ISomething. In other words, if ISomething were declared like:
public interface ISomething
{
public string SomeProperty { get; set; }
}
Then you could access MyProperty.SomeProperty. If you omitted the where T : ISomething then you wouldn't be able to access SomeProperty since T would only be known to be of type object.
Type Safety. For example, suppose you're creating a container. You can pass in something to that container and retrieve it in the proper form without having to do any casts later by parameterizing the container. You're simply defining constraints on the types of things that you're willing to store in your container.
Here's an example of the difference, by just using List<>
Image list wouldn't be generic but it would just use IListElement everywhere it used the generic instead. Now Imagine you have an object that's something like this.
class Element : IListElement
{
public string Something { get; set; }
}
now I could just do list.Add(element); and there wouldn't be a difference with a real List<Element>. However when I retreive data it's a different story, if I use the list that uses IListElement then I have to cast my data back so I can get the Something out of it. Thus i'd have to do:
string s = ((Element)list[0]).Something;
while with the generic I can just do:
string s = list[0].Something;
saves a lot of trouble, ofcourse it goes a bit further than that but I think you can get the idea from this.
Well for a start, you can call methods defined in ISomething within the code for the generic method / methods on the generic class. If T was allowed to be any type then this would not be possible (although you could always do some runtime casting).
So it allows you to enforce compile-time constraints on what T can be and therefore rely on these constraints when you write the code - turning runtime errors into compile time errors.
Yes you can use ISomething in place of T , but that will manually close the generic type to an ordinary class. It wont be a generic type any more. By using T, you keep the type open to as many ISomething subtypes as you want. Code reuse without compromising type safety is the key benefit here. For example if you use a Stack of ISomethings, you can push any ISomething onto the stack but a pop has to occur with a downcast to the actual subtype of ISomething for it to be useful. Downcasting creates a potential failure point, which will not be there in a generic Stack<T> where T:ISomething
Consumer of your class gets the benefit of increased type-safety, among others.
class Widget : IPokable { }
// No generics
Widget w = (Widget)list[0]; // cast can fail
// With generics
Widget w = list[0];
Without generics, if list was containing IPokable objects, cast is still necessary.
Class you're implementing gets the benefit of using specific methods on the generic object.
class PokableList<T> where T : IPokable {
public T PokeAndGet() {
currentObj.Poke();
return currentObj;
}
}
Perhaps this simple example might help.
If I have these classes:
public class ListOfCars<T> : List<T> where T : Car { }
public abstract class Car { }
public class Porsche : Car { }
public class Bmw : Car { }
...and then if I write this code:
var porsches = new ListOfCars<Porsche>();
// OK
porsches.Add(new Porsche());
//Error - Can't add BMW's to Porsche List
porsches.Add(new Bmw());
You can see that I can't add a BMW to a Porsche list, but if I just programmed off of the base class it would be allowed.
I was wondering if anyone could tell me if this kind of behaviour is possible in C# 4.0
I have an object hierarchy I'd like to keep strongly typed. Something like this
class ItemBase {}
class ItemType<T> where T : ItemBase
{
T Base { get; set; }
}
class EquipmentBase : ItemBase {}
class EquipmentType : ItemType<EquipmentBase> {}
What I want to be able to do to have something like this
ItemType item = new EquipmentType();
And I want item.Base to return type ItemBase. Basically I want to know if it's smart enough to strongly typed generic to a base class without the strong typing. Benefit of this being I can simply cast an ItemType back to an EquipmentType and get all the strongly typedness again.
I may be thinking about this all wrong...
You're talking about covariance which would allow you to do:
ItemType<object> item = new EquipmentType();
You couldn't do this in C# 4 because of the following reasons:
Generic covariance only works on interfaces, arrays, and delegate types, not base classes
Your ItemType class uses T as an in/out type parameter meaning it receives a T and also returns a T.
Number 2 is the main issue because if it were allowed, then the following code would have to be compilable, yet fail at runtime.
// this will not work
ItemType<object> item = new EquipmentType();
item.Base = new Object(); // this seems ok but clearly isn't allowed
Covariance and Contravariance FAQ
No, because ItemType as far as the compiler is concerned is a separate type from ItemType<EquipmentBase> or ItemType<Foo>. All three are treated as unique types and they cannot represent one another.
In your class declarations, you declared it as ItemType<T> and so ItemType would be an undefined type which would not compile.
At best, you could use an ItemType<EquipmentBase> object to represent EquipmentType or any other class derived from ItemType<EquipmentBase> but not ItemType<PersonType>.
I don't think that the new features of C# 4.0 will help you out there. However, there is a way around this which already works since generics were introduced: you create an abstract base class with the same name as the generic class and put all members which you want and which don't need to accept or return an argument of the generic type, like so:
class ItemBase {
}
abstract class ItemType {
public ItemBase Base {
get { return GetItemBase(); }
set { SetItemBase(value); }
}
protected abstract void SetItemBase(ItemBase value);
protected abstract ItemBase GetItemBase();
}
class ItemType<T> : ItemType where T : ItemBase {
protected override sealed void SetItemBase(ItemBase value) {
Base = (T) value;
}
protected override sealed ItemBase GetItemBase() {
return Base;
}
public new T Base { get; set; }
}