Generic List of Generic Objects

Generic list of generic objects

Yes, generics is a good choice. The key to achieving type-safety (and being identify the type with the Type property is to add an abstraction between the list and Field<T> class.

Have Field<T> implement the interface IField. This interface doesn't need any members.

Then declare your list as being List<IField>.

That way you constrain the list to only contain fields, but each field can be of a different type.

To then read the values later, just do

foreach(var field in list)
{
var type = field.Type;
....
}

A generic list of generics

This is situation where it may benefit you to have an abstract base class (or interface) containing the non-generic bits:

public abstract class Field
{
public string Name { get; set; }
public string Description { get; set; }
}

public class Field<T> : Field
{
public T Value { get; set; }

/*
...
*/
}

Then you can have a List<Field>. That expresses all the information you actually know about the list. You don't know the types of the fields' values, as they can vary from one field to another.

How to return Generic List with Generic Class Object in c#?

You can't use generic type with the List without specifying type parameter explicitly. Alternatively, you can create a base class or interface that would be a parameter for the List.

I mean:

        public static List<ITable> GetTables()
{
var tbls = new List<ITable>();
tbls.Add(new Table<Table1> { Name = "Table1"});
tbls.Add(new Table<Table2> { Name = "Table2"});
tbls.Add(new Table<Table3> { Name = "Table3"});
return tbls;
}

public class Table<T> : ITable
{
public T TableInstance { get; set; }
public Type TableType => typeof(T);
public string Name { get; set; }
}

public interface ITable
{
Type TableType { get; }
public string Name { get; set; }
}

Adding generic object to generic list in C#

I don't think you can do this in C#... you would have to add the type parameter to the class:

class C<T> {
void Method(SomeClass<T> obj) {
list.Add(obj);
}
List<SomeClass<T>> list = new List<SomeClass<T>>();
}

The other option would be to use an interface:

class C {

void Method<T>(T obj)
where T : ISomeClass {
list.Add(obj);
}
List<ISomeClass> list = new List<ISomeClass>();
}

Generic list of generics with same base class

Change

var carArea = new Area<Car> { Vehicles = new List<Car>() };
var bikeArea = new Area<Bike> { Vehicles = new List<Bike>() };

To

var carArea = new Area<Vehicle> { Vehicles = new List<Car>() };
var bikeArea = new Area<Vehicle> { Vehicles = new List<Bike>() };

Now your carArea and bikeArea is a Area<Vehicle> (which your garage expects) and each have its own related vehicles, which will work in your methods.

and to get the type of vehicle in the list:

if(area.GetType() == typeof(List<Car>))
{

}

How to make a List of Generic Objects?

Is there a way I can define a member with a type that mans "Children classes will contain a _valeur class variable, I don't know what type is that variable, children will define it".

Sure - use object as the type:

protected object _valeur;

Think about it - if _valeur can be of different types - how do you know what type you're dealing with at compile time? And so how do you use it?


Take List<T> for example - suppose you want a List<List<?>>, where the inner list can be of any type. Right now you can use List<object>, you can even use List<IEnumerable<object>> to guarantee that the inner lists are at least some form of IEnumerable<T>. But let's suppose your syntax existed:

var funkyList = new List<List<?>>();

I can now add lists of any type:

funkyList.Add(new List<int>());
funkyList.Add(new List<Foo>());
funkyList.Add(new List<Bar>());

Now you extract one of the inner Lists:

List<?> l = funkyList[1];

But what is ?? If you don't know what the type of the list is, how are you going to do anything useful with it? At best you'd have to use reflection (or dynamic) to get the inner type anyways, which negates the power of generics.

List of generic objects compared to single generic object

First: Dont use raw types. What is a raw type and why shouldn't we use it?

A way to fix your code would be to introduce type paramters to the methods of the factory.

class Factory{
public static <T> GenericObject<T> getSingleInstance()
{
return new GenericObject<T>();
}

public static <T> List<GenericObject<T>> getListOfInstance()
{
List<GenericObject<T> genericObjectList=new ArrayList<>();
genericObjectList.add(new GenericObject<T>());
genericObjectList.add(new GenericObject<T>());
return genericObjectList;
}
}

Reading Generic Value from List of Generic Objects

You have syntax errors in the code like the lacking public scope of your enums and ConditionOperator.Equal (not ConditionOperator.Equals) but that asside here is the fix.

  1. Conditions should be of type List<ConditionBase>
  2. Use OfType on the List to retrieve and cast the resulting type to Condition<string>. I assume that this was your intention with your added check c.GetType() == typeof(string)
string url = "";
List<ConditionBase> Conditions = new List<ConditionBase>();
Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal));
Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual));

foreach (var c in Conditions.OfType<Condition<string>>())
{
url += c.Field + " " + c.ConditionOperator + " '" + c.Value + "' and ";
}

If you want a generic property that you can access on all instances regardless of the generic type constraint then you would need to extend the base interface accordingly.

public interface ConditionBase
{
Field Field { get; set; }
ConditionOperator ConditionOperator { get; set; }
object FieldValue { get; }
}

public class Condition<T> : ConditionBase
{
/* I only included the added code in this type */
public object FieldValue
{
get { return (object) this.Value; }
}
}
string url = "";
List<ConditionBase> Conditions = new List<ConditionBase>();
Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal));
Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual));

foreach (var c in Conditions)
{
url += c.Field + " " + c.ConditionOperator + " '" + c.FieldValue + "' and ";
}

It seems you want to output your value to a string based on the changes in your question. Add a string formatter to your type.

/* I only included the added code in this type */
public class Condition<T> : ConditionBase
{
private Func<T, string> _formatValue;
public Condition(Field field, T value, ConditionOperator condition, Func<T, string> formatValue)
{
this._Field = field;
this._Value = value;
this._ConditionOperator = condition;
this._formatValue = formatValue;
}

public override string ToString()
{
return this._formatValue(this.Value);
}
}
string url = "";
List<ConditionBase> Conditions = new List<ConditionBase>();
Conditions.Add(new Condition<int>(Field.Field1, 1, ConditionOperator.Equal, (val)=> val.ToString()));
Conditions.Add(new Condition<string>(Field.Field2, "test", ConditionOperator.NotEqual, (val)=> val));

foreach (var c in Conditions)
{
url += c.Field + " " + c.ConditionOperator + " '" + c.ToString() + "' and ";
}

Adding Object to Generic List with two types

List<SubClaz> is not a subtype of List<SuperClaz> in Java. That's why the wildcards are used: List<SubClaz> is a subtype of List<? extends SuperClaz>.

Now for your A<B<?>> abcv=new A<B<String>>(); example:

By adding the wildcard, you're making B<String> a subtype of B<?>, but since these are also wrapped by another type A, we're back to the first problem:

A<B<String>> is not a subtype of A<B<?>>

(Notice B<?> is the SuperClaz and B<String> is the SubClaz in this case).

You can fix this the same way; by adding another wildcard:

A<B<String>>() is a subtype of A<? extends B<?>>.

Keep in mind that this doesn't allow you to read or manipulate the list as you want. Search for covariance and contravariance for more detail. Here is a good one: http://bayou.io/draft/Capturing_Wildcards.html



Related Topics



Leave a reply



Submit