Cannot cast IEnumerable<ViewmodelA> to IEnumerable<ViewmodelB> - c#

I retrieve a list with the type of IEnumerable<ViewmodelA> and need to cast this list to IEnumerable<ViewmodelB>. There are same and different properties in each viewmodel and I just want to map the same properties (Name and Surnmame). Is it possible using boxing or AutoMapper? I tried boxing but it is not working :(
IEnumerable<ViewmodelB> newList;
newList = (IEnumerable<ViewmodelB>)demoService.GetList(); //returns IEnumerable<ViewmodelA>
ViewodelA:
public class ViewmodelA {
public string Name { get; set; }
public string Surname { get; set; }
public string School { get; set; }
public string Number { get; set; }
}
ViewodelB:
public class ViewmodelB {
public string Name { get; set; }
public string Surname { get; set; }
public string Work { get; set; }
public string Address { get; set; }
}

You won't be able to cast ViewmodelA to ViewmodelB.
The first few options that come to my mind are:
make both classes inherit from the same base class,
make both classes implement an interface,
create a conversion mechanism between A and B.

For something so trivial as this operation I think I would just:
var modelbs = modelas.Select(
a => new Viewmodelb(){
Name = a.Name,
Surname = a.Surname
}
);
You could make both viewmodels inherit from a base that has the Name and Surname in it, though note that this wouldn't allow you to cast a modela into a modelb, you could only cast the modela into the base class.
Or you could provide a constructor in modelb that takes a modela object and pulls just the name/surname out of it and use it like:
var modelbs = modelas.Select(
a => new Viewmodelb(a)
);
Your class ViewmodelB would look like:
public class ViewmodelB {
public string Name { get; set; }
public string Surname { get; set; }
public string Work { get; set; }
public string Address { get; set; }
public ViewmodelB(ViewmodelA x){
Name = x.Name;
Surname = x.Surname;
//maybe initialize other properties here
}
}

You can only do:
IEnumerable<ViewmodelB> newList = demoService.GetList().Select(a => SomeMethodCreatingBFromA(a));
Where SomeMethodCreatingBFromA can be anything - call constructor, AutoMapper, whatever. Didn't use AutoMapper to much, but I suppose it has a method that converts between collections.

If you just want to use the common properties, create a base class or an interface, where you define the common properties and derive both classes from that. Then you can use the base class or interface.

Here are examples for #tymtam answer
Make both classes inherit from the same base class
Make both classes implement an interface
Create a conversion mechanism between A and B
{
/// <summary>
/// Using the same base class
/// </summary>
public class BaseClass
{
public string Property { get; set; }
}
public class ViewModelA : BaseClass
{
public string Property { get; set; }
}
public class ViewModelB : BaseClass
{
public string Property { get; set; }
}
/// <summary>
/// Using the same interface
/// </summary>
public interface BaseInterface
{
string Property { get; set; }
}
public class ViewModelA : BaseInterface
{
public string Property { get; set; }
}
public class ViewModelB : BaseInterface
{
public string Property { get; set; }
}
/// <summary>
/// Create a conversion mechanism. This can be done in either in ViewModelA or ViewModelB
/// </summary>
public class ViewModelA
{
public string Property { get; set; }
public static implicit operator ViewModelA(ViewModelB model) => new ViewModelA { Property = model.Property };
public static implicit operator ViewModelB(ViewModelA model) => new ViewModelB { Property = model.Property };
}
public class ViewModelB
{
public string Property { get; set; }
}

Related

Passing values from concretized instance of an base class to another base class instance

I am currently working on making viewmodels capable of parsing data extracted from database to the UI and vice versa, and to do so I do a lot of manual mapping between my two viewmodels.
Currently I try to pass some values that determines an attribute, but since each attributetype requires specifying a lot specific parameter, and 90% of the variables will be redundant in all cases since attributes only have one type..
Thus i have create a placeholder base class, which just contains an Id, that each atttribute have,
and each of the specific attribute type parameter will then use this placeholder as base class..
example:
public class BooleanViewSpecification : AttributeTypeSpecification
{
public string TrueOptionText { get; set; }
public string FalseOptionText { get; set; }
}
public class DateTimeTypeViewSpecification : AttributeTypeSpecification
{
public DateTime EarliestDataTime { get; set; }
public DateTime LatestDataTime { get; set; }
}
and my Attribute class is just an
public class AttributeView
{
public DataType Type { get; set; }
public AttributeTypeSpecification AttributeTypeViewSpecification { get; set; }
}
And the same Goes for my DB view model
public class BooleanSpecification : AttributeTypeSpecification
{
public string TrueOptionText { get; set; }
public string FalseOptionText { get; set; }
}
public class DateTimeTypeSpecification : AttributeTypeSpecification
{
public DateTime EarliestDataTime { get; set; }
public DateTime LatestDataTime { get; set; }
}
and my Attribute class is just an
public class Attribute
{
public DataType Type { get; set; }
public AttributeTypeSpecification AttributeTypeSpecification { get; set; }
}
Problem is then mapping from one class to another class
public static IEnumerable<AttributeView> MapToViewModel(this IEnumerable<Attribute> attributes)
{
return attributes.Select(z => new AttributeView()
{
Type = z.Type,
AttributeTypeViewSpecification = z.AttributeTypeSpecification
});
}
Which does not seem to work?
I use entity framework and migrate using Code-First what I receive is the Id of the location, and not the actual values?
I cant seem to understand why I cant be given the values - if it during the mapping does have the value?
So why cant they be mapped over?
I retrieve the value
Context.Include(Attribute).ThenInclude(AttributeTypeSpecification)
The only thing I receive is the actual Id rather than the specified entries?

property inheritance without valuing joint

I want to inherit some properties that are the same in 2 classes using interface or abstract class; I don't want to declare variable in child classes.
Is it possible to do this?
Parent Class:
interface IError
{
DateTime GETDATE { get; set; }
string ERROR_NUMBER { get; set; }
string ERROR_SEVERITY { get; set; }
string ERROR_STATE { get; set; }
string ERROR_PROCEDURE { get; set; }
string ERROR_LINE { get; set; }
string ERROR_MESSAGE { get; set; }
}
Child :
public class Business
{
public Business()
{
this.Id = -1;
this.Message = "";
}
public int Id { get; set; }
public string Message { get; set; }
}
Another child:
public class DbTools
{
//Another Class
}
I need parent properties in this two classes, but if change code like below, I should use another variable that I don't want to:
public class Business : IError
{
private DateTime m_GetDATE;//I don't want to declare another variable
public DateTime GETDATE
{
get { return m_GetDATE; }
set { GETDATE = m_GetDATE; }
}
}
Sounds like you want an abstract base class:
public abstract class ErrorBase : IError
{
public DateTime GETDATE { get; set; }
//...ditto all the other IError properties
}
Then you can just inherit that:
public class Business : ErrorBase
{
// all the ErrorBase properties are inherited
}
You could also make the base class properties virtual just in case you need to override them in the derived classes at any point.
The other thing you might consider is composing rather than inheriting. It doesn't seem all that natural that Business and DbTools should be inheriting from the same base class, so instead have a (non-abstract) ErrorBase class that implements IError and have Business and DbTools have an Error property:
public class ErrorBase : IError
{
public DateTime GETDATE { get; set; }
//...ditto all the other IError properties
}
public interface IHaveError
{
ErrorBase Error { get; set; }
}
public class Business : IHaveError
{
public ErrorBase { get; set; }
}
As a bonus, you could make IHaveError actually be IHaveErrors and have a List<ErrorBase> property allowing your objects to hold more than one error, which might be useful sometimes.

C#: Extracting to an interface a class that has another class inside - or is there a better way?

I have a class below, i have extracted all the properties to a Interface but i don't seem to be able to extract it... Obviously create a new object like
ITestItem item = new TestItem();
doesn't give me access to Properties which is an instance of Meta class.
I also wanted to stop anyone from create an instance of Meta class outside of TestItem... i tried marking it as internal but that would allow me because Properties is public.
Also i am unsure whether i need to have an interface for META??
here is my class... can anyone help?
public class TestItem : ITestItem
{
public bool Enabled { get; set; }
public Meta Properties = new Meta();
public List<int> Items { get; set; }
public class Meta
{
internal Meta
{
}
public string Name { get; set; }
}
public TestItem()
{
this.Items = new List<int>();
}
}
EDIT
I have uppdated the class above to include an internal constructor for Meta so it can't be instanciated outside the class.
Here is my interface i have (as suggested by giddy)... It says now that it doesn't implement Properties
public interface ITestItem
{
bool Enabled { get; set; }
Meta Properties { get; set; };
List<int> Items { get; set; }
}
So you would:
Not want to maybe use the term extract to interface, maybe your idea about interfaces is a little wrong. You want to do some reading here.
Define the Meta class inside the Test class. Mark the constructor internal or private depending on where you want to create an instance.
Make a property that exposes the Meta class outside of the Test class
public class TestItem : ITestItem
{
public TestItem()
{
this.Properties = new Meta();//set it from here
this.Items = new List<int>();
}
public bool Enabled { get; set; }
//make it private set if you don't want an outsider setting it
public Meta Properties {get;private set}
public List<int> Items { get; set; }
public class Meta
{//make it private if you only create an instance here.
internal Meta(){}
public string Name { get; set; }
}
}
You also add the Meta property to your interface:
public interface ITestItem
{
bool Enabled { get;set;}
Meta Properties { get;set;}
List<int> Items { get;set;}
void ScheduleItem();
}
You may try this one. Its compiled in VS2010. It is better anyway to extract an interface for Meta also for the sake of "decoupling classes" to allow unit testing. Please search and read about - "decoupling classes".
public class Meta { // Do not make this class a child class for flexibility and testing purposes.
public string Name { get; set; }
}
public class IMeta {
string Name { get; set; }
}
public class TestItem : ITestItem {
public TestItem() {
this.Meta = new Meta();
this.Items = new List<int>();
public bool Enabled { get; set; }
public IMeta Meta { get; internal set; }
public List<int> Items { get; set; }
}
public interface ITestItem {
bool Enabled { get; set; }
IMeta Meta { get;}
IList<int> Items { get; set; }
}

Alternatives to nested interfaces (not possible in C#)

I'm using interfaces in this case mostly as a handle to an immutable instance of an object. The problem is that nested interfaces in C# are not allowed. Here is the code:
public interface ICountry
{
ICountryInfo Info { get; }
// Nested interface results in error message:
// Error 13 'ICountryInfo': interfaces cannot declare types
public interface ICountryInfo
{
int Population { get; }
string Note { get; }
}
}
public class Country : ICountry
{
CountryInfo Info { get; set; }
public class CountryInfo : ICountry.ICountryInfo
{
int Population { get; set; }
string Note { get; set; }
.....
}
.....
}
I'm looking for an alternative, anybody would have a solution?
VB.NET allows this. So, you can create a VB.NET assembly only with the interface definitions that you need:
Public Interface ICountry
ReadOnly Property Info() As ICountryInfo
Public Interface ICountryInfo
ReadOnly Property Population() As Integer
ReadOnly Property Note() As String
End Interface
End Interface
As for the implementation, C# does not support covariant return types, so you must declare your class like this:
public class Country : ICountry {
// this property cannot be declared as CountryInfo
public ICountry.ICountryInfo Info { get; set; }
public class CountryInfo : ICountry.ICountryInfo {
public string Note { get; set; }
public int Population { get; set; }
}
}
If the end goal is to use this with dependency injection, what's wrong with injecting them into each other instead of nesting?
public interface ICountry
{
ICountryInfo Info { get; }
}
public interface ICountryInfo
{
int Population { get; set; }
string Note { get; set; }
}
and implement as:
public class Country : ICountry
{
private readonly ICountryInfo _countryInfo;
public Country(ICountryInfo countryInfo)
{
_countryInfo = countryInfo;
}
public ICountryInfo Info
{
get { return _countryInfo; }
}
}
public class CountryInfo : ICountryInfo
{
public int Population { get; set; }
public string Note { get; set;}
}
Then once you set up your bindings for ICountry & ICountryInfo, CountryInfo will inject into Country whenever Country is injected.
You could then restrict the binding, if you wanted, to only inject CountryInfo into Country and nowhere else. Example in Ninject:
Bind<ICountry>().To<Country>();
Bind<ICountryInfo>().To<CountryInfo>().WhenInjectedInto<Country>();
You can use namespaces like this:
namespace MyApp
{
public interface ICountry { }
namespace Country
{
public interface ICountryInfo { }
}
}
Then in MyApp namespace you can use Country.ICountryInfo which is close to your requirement. Also using alias helps make the code clear.
This will work just fine, no need to nest:
public interface ICountry
{
ICountryInfo Info { get; }
}
public interface ICountryInfo
{
int Population { get; }
string Note { get; }
}
If ICountryInfo has no reason to exist outside ICountry, then why shouldn't you just put the properties of ICountryInfo in ICountry and dismiss the idea of nested interfaces?
An interface that hasn't a meaning of its own without another interface doesn't make sense to me, as an interface on itself is useless if not implemented by a class.

c# Class Design with Generics

How can i make the following class as general as possible (for maximum reuse) without creating too many classes of the same type, albeit with one extra property.
I want to avoid writing 3 slightly different versions of the same class
1# Class with No SubContent
public class Content
{
public string PageName { get; set; }
}
2# Class with Subcontent
public class Content
{
public string PageName { get; set; }
public IList<Content> SubContent {get; set;} //same as class
}
3# Class with sub content of another type
public class Content
{
public string PageName { get; set; }
public IList<DetailContent> SubContent {get; set;} //Note the different def
}
Of course i can create a generic class, but i find this confusing for consumers. It is inferring that the class is of Type T, when in fact its the Property that requires the type
public class Content<T>
{
public string PageName { get; set; }
public IList<T> SubContent {get; set;} //Note the different def
}
Generic Properties are not supported. So are there any patterns or suggestion on how i can handle this problem?
Perhaps you can have a look at the Composite Design Pattern
whats wrong with:
public class Content<T>
{
public string PageName { get; set; }
public IList<T> SubContent { get; set; } //Note the different def
}
?
it works you know...
What about
public class Content
{
public string PageName { get; set; }
}
public class ContentWithSubContent<T> : Content
{
public IList<T> SubContent { get; set; }
}
and if you want to be able to access SubContent not knowing the actual type, you could use
public class Content
{
public string PageName { get; set; }
}
public interface IContentWithSubContent
{
IEnumerable SubContent { get; }
}
public class ContentWithSubContent<T> : Content, IContentWithSubContent
{
public IList<T> SubContent { get; set; }
IEnumerable IContentWithSubContent SubContent
{
get { return this.SubContent; }
}
}
that way you can access the SubContent property bypassing generics if you need to, by using IContentsWithSubContent rather than Content.
Why not make an interface for the content classes:
public interface IContent {
public function GetContent()
}
and then you can use
List<IContent> in your content class?
you could even make the interface generic

Categories

Resources