user1091406
user1091406

Reputation: 163

Generic objects in c#

i have a litte problem and i need some help :)

For example i have a simle abstract class

public abstract class BaseDefinition
{
    public int Id { get;set; }
    public string Name { get;set; }
}

and other base class

public abstract class BaseParentClass
{
    public string Name { get;set; }
    public string Schema { get;set; }
}

and first generic abstract class

public abstrac class BaseParentClass<T> : 
    BaseParentClass where T : BaseDefinition
{
    public IList<T> Objects {get;set;}
}

and first implementations

public class ClassADefintion : BaseDefinition
{
    public bool IsChanged {get;set;}
}


public class ClassAObject : BaseParentClass<ClassADefinition>
{
     public bool OtherField {get;set;}
}

public class ClassBDefintion : BaseDefinition
{
    public bool IsBBBChanged {get;set;}
}

public class ClassBObject : BaseParentClass<ClassBDefinition>
{
     public bool OtherBBBBField {get;set;}
}

Sorry for class name, but I can't create anything better (it's only example) As We see, now is all OK :).

I have some methods who returns a IEnumerable of generic implementation

IEnumerable<ClassBObject> ClassBObjectCollection;
IEnumerable<ClassAObject> ClassAObjectCollection;

Now i must create a method, who can take a generic objects in IEnumerable

public void DoWork(IEnumerable<BaseParentClass<BaseDefinition>> objects)
{
    foreach(var baseObj in objects)
    {
        foreach(var baseDef in baseObj.Objects)
        {
            // do some work
        }
    }
}

How i remember BaseObject<BaseDefinition> != ClassAObject, but compiler doesn't put on screen any errors. I remember in .NET in generic interface We can use IN and OUT T, so i try make this

public interface IBaseParentClass<out T> where T : BaseDefinition
{
    IList<T> Objects {get;set;}
}

Yup, You can't make a List of <out T>. Somebody have any idea for this problem ?

I can get this fields values by reflection, but i have abstract class and interface so i think is a better way.

Upvotes: 4

Views: 584

Answers (1)

flq
flq

Reputation: 22839

I don't have a compiler at hand, but I think it should be possible to rewrite DoWork as such:

public void DoWork<T>(IEnumerable<BaseObject<T>> objects) 
    where T : BaseDefinition
{
    foreach(var baseObj in objects)
    {
        foreach(var baseDef in baseObj.Objects)
        {
            // do some work
        }
    }
}

I am not sure whether the compiler will be able to infer T for you, try it out.

Another possibility may be that if you enumerate those objects anyway, to make Objects of Type IEnumerable(Of T).

Upvotes: 2

Related Questions