Convert ListDerivedClass to ListBaseClass
The way to make this work is to iterate over the list and cast the elements. This can be done using ConvertAll:
List<A> listOfA = new List<C>().ConvertAll(x => (A)x);
You could also use Linq:
List<A> listOfA = new List<C>().Cast<A>().ToList();
Cannot convert from ListDerivedClass to ListBaseClass
It is because List<T>
is in-variant
, not co-variant
, so you should change to IEnumerable<T>
which supports co-variant
, it should work:
IEnumerable<BaseClass> bcl = new List<DerivedClass>();
public void doSomething(IEnumerable<BaseClass> bc)
{
// do something with bc
}
Information about co-variant in generic
C# Moq - Cannot convert ListDerivedClass to ListBaseClass
Because List<DerivedClass>
does not derive from List<BaseClass>
and the fact that the T
inside does is irrelevent when looking at it from that perspective.
What you're looking for is Covariance. There's MSDN documentation on it here: https://docs.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance
Convert List of Base Class to a List of Derived Class - possible?
Cast<T>
method applies cast operation to all elements of the input sequence. It works only if you can do the following to each element of the sequence without causing an exception:
ParentClass p = ...
ChildClass c = (ChildClass)p;
This will not work unless p
is assigned an instance of ChildClass
or one of its subclasses. It appears that in your case the data returned from the server API contains objects of ParentClass
or one of its subclasses other than ChildClass
.
You can fix this problem by constructing ChildClass
instances, assuming that you have enough information from the server:
List<ChildClass> childList = parentList
.Select(parent => new ChildClass(parent.Name, ... /* the remaining fields */))
.ToList();
Copying a ListBaseClass to ListDerivedClass
List<DerivedClass> result =
listBaseClass.ConvertAll(instance => (DerivedClass)instance);
Actually ConvertAll is good when you need to create new objects based on the original, when you just need to cast you can use the following
List<DerivedClass> result =
listBaseClass.Cast<DerivedClass>().ToList();
If not all of the items in your list can be cast to DerivedClass then use OfType instead
List<DerivedClass> result =
listBaseClass.OfType<DerivedClass>().ToList();
C# convert Listbaseclass to ListDerivedClass
In your GetSensors
method, you are creating instances of the base class Sensor
. Trying to implicitly cast them to some other derived class is not possible. You should use a generic type parameter in that method and create instances of the actual derived type.
Like so: (notice the where
clause and the new
constraint of the T
parameter)
public static List<T> GetSensors<T>(JToken jToken) where T : Sensor, new()
{
var sensors = new List<T>();
try
{
foreach (var item in jToken)
{
var s = new T();
s.Label = item["lab"].ToString();
s.ActualTemp = item["tf"] != null ? item["tf"].ToString() : "";
s.HighTemp = item["hf"] != null ? item["hf"].ToString() : "";
s.LowTemp = item["lf"] != null ? item["lf"].ToString() : "";
sensors.Add(s);
}
}
catch (Exception)
{
}
return sensors;
}
Now call it like this:
List<IntSensor> iSensors = ParseJsonData.GetSensors<IntSensor>(internalSensorTree);
Cannot add a derived class object to a list of it's base class type
One possible solution would be to introduce a covariant interface:
public interface IBase<out T> where T : Model
{
T Data { get; }
}
public abstract class BaseClass<T> : IBase<T> where T : Model
Then use the interface for your list:
var myBaseList = new List<IBase<Model>>();
myBaseList.Add(new BaseClassA(new ModelA()));
myBaseList.Add(new BaseClassB(new ModelB()));
Because IBase
declares Data
as get-only, this ensures type-safety.
And here you still have access to Data
:
foreach (var item in myBaseList)
{
if (item.Data.Id > 0)
{
//do stuff
}
}
Casting List of Derived class to List of base class
The reason you cannot do this is because a list is writable. Suppose it were legal, and see what goes wrong:
List<Cat> cats = new List<Cat>();
List<Animal> animals = cats; // Trouble brewing...
animals.Add(new Dog()); // hey, we just added a dog to a list of cats...
cats[0].Speak(); // Woof!
Well dog my cats, that is badness.
The feature you want is called "generic covariance" and it is supported in C# 4 for interfaces that are known to be safe. IEnumerable<T>
does not have any way to write to the sequence, so it is safe.
class Animal
{
public virtual void Play(IEnumerable<Animal> animals) { }
}
class Cat : Animal
{
public override void Play(IEnumerable<Animal> animals) { }
}
class Program
{
static void Main()
{
Cat cat = new Cat();
cat.Play(new List<Cat>());
}
}
That will work in C# 4 because List<Cat>
is convertible to IEnumerable<Cat>
, which is convertible to IEnumerable<Animal>
. There is no way that Play can use IEnumerable<Animal>
to add a dog to something that is actually a list of cats.
convert listbaseclass in Listderivedclass
Why do you inherit the Product
class? I think you want to add 2 more fields to the Product
class, right?
Because the auto-generated class is a partial
class, instead of inheriting the Product
class as you did, just add one more file to the partial class like this:
public partial class Product
{
public bool Restock { get; set; }
public DateTime? DateSold { get; set; }
}
C#, How to pass a List of a Derived class to a method that receives a List of the Base class?
The reason for such behaviour is explained here. In short - classes do not support variance in C# and List<AppleBox>
is not List<FruitBox<Apple>>
.
What you can do:
- "convert" collection (actually create a new one):
with OfType<>().ToList()
AppleBox.ChooseFirst(appleBoxes.OfType<FruitBox<Apple>>().ToList())
or just ToList
AppleBox.ChooseFirst(appleBoxes.ToList<FruitBox<Apple>>())
- change
ChooseFirst
signature to work with covariantIEnumerable<out T>
interface:
public abstract class FruitBox<T>
{
public T item;
public static T ChooseFirst(IEnumerable<FruitBox<T>> fruitBoxes)
{
return fruitBoxes.First().item;
}
}
Related Topics
How to Auto-Generate a C# Class File from a Json String
The Entity Cannot Be Constructed in a Linq to Entities Query
Random Number Generator Only Generating One Random Number
Post an HTML Table to Ado.Net Datatable
Decimal VS Double! - Which One Should I Use and When
Convert List≪Derivedclass≫ to List≪Baseclass≫
Sending Email in .Net Through Gmail
How to Create an Excel (.Xls and .Xlsx) File in C# Without Installing Microsoft Office
How to Check If a File Is in Use
Parsing CSV Files in C#, With Header
Split List into Sublists With Linq
Encrypt and Decrypt a String in C#
Send Http Post Request in .Net
What Is an Indexoutofrangeexception/Argumentouto
frangeexception and How to Fix It