Type Casting Exception With Inheritance - c#

Here is my code below. It gives me Casting exception problem at selIngs.Add(da). tried with the 2nd way. it still give me the same exception. I wonder where I am doing wrong? Once I implement the interface or inherit the base class it should be ok to treat child class as the same. Any idea please?
//1st way
public interface IngredientInterface
{
double Concentration { get; set; }
string DateCreated { get; set; }
string DevCode { get; set; }
}
public class IngredientData : INotifyPropertyChanged, IngredientInterface
{
public string GroupCode
{
get { return groupCode; }
set
{
groupCode = value;
}
}
public double Setpoint { get; set; }
public bool IsHighlighted { get; set; }
public double PPT { get; set; }
}
public class FormulaUploadViewModelData: IngredientData
{
//.....
}
public class FormulaUploadViewModel :INotifyPropertyChanged
{
public FormulaUploadViewModel()
{
selIngs = new List<FormulaUploadViewModelData>();
}
private void IngsUp()
{
List<IngredientData> someIngData = new List<IngredientData>();
foreach (FormulaUploadViewModelData da in someIngData)
{
selIngs.Add(da); //here gives me casting exception
}
}
}
//2nd way
public class FormulaUploadViewModelData: IngredientInterface
{
//.....
}
public class FormulaUploadViewModel :INotifyPropertyChanged
{
public FormulaUploadViewModel()
{
selIngs = new List<FormulaUploadViewModelData>();
}
private void IngsUp()
{
List<IngredientInterface> someIngData = new List<IngredientInterface>();
foreach (FormulaUploadViewModelData da in someIngData)
{
selIngs.Add(da); //here gives me casting exception
}
}
}

All FormulaUploadViewModelData are IngredientInterface. So this will work:
var ingredients = new List<IngredientInterface>();
ingredients.Add(new FormulaUploadViewModelData());
But the opposite does not work because not all IngredientInterface are FormulaUploadViewModelData which is what should follow from allowing:
var formulas = new
List<FormulaUploadViewModelData>();
formulas(someIngredientInterface);
Solution? Make sure the da you are adding is in fact a FormulaUploadViewModelData. There is quite a few ways to do it, to name a couple:
Pattern matching
foreach (var da in someInData)
if (da is FormulaUploadViewModelData formula)
selIngs.Add(formula)
Use Enumerable.OfType<> extension method
foreach (var formula in
someInData.OfType<FormulaUploadViewModelData>())
selIngs.Add(formula)
Etc.

Related

Builder Design Pattern C#

there is a concept about inheritance which I do not quite understand.
I have a
protected DeveloperReport DeveloperReport; // Field
Wouldn't PersonalInfoBuilder be able to access that field ?
If yes,
public PersonalInfoBuilder MyPersonalInfo => new PersonalInfoBuilder(DeveloperReport);
Why do I still have to pass the DeveloperReport(field) into PersonalInfoBuilder constructor, when I can
just modify the protected DeveloperReport field by calling new PersonalInfoBuilder(), instead of
new PersonalInfoBuilder(DeveloperReport)?
And, how the concept of "return this" return the changes made to DeveloperReport(field) back to
DeveloperReportBuilder?
Thanks !
class DeveloperReport
{
// Properties
public int Id { get; set; }
public string Name { get; set; }
public DeveloperLevel Level { get; set; }
public int WorkingHours { get; set; }
public int HourlyRate { get; set; }
// Methods
public double CalculateSalary() => WorkingHours * HourlyRate;
}
class DeveloperReportBuilder
{
protected DeveloperReport DeveloperReport;
public PersonalInfoBuilder MyPersonalInfo => new PersonalInfoBuilder(DeveloperReport);
public DeveloperReportBuilder()
{
DeveloperReport = new DeveloperReport();
}
// return developer report.
public DeveloperReport Build() => DeveloperReport;
}
class PersonalInfoBuilder : DeveloperReportBuilder
{
public PersonalInfoBuilder(DeveloperReport report)
{
DeveloperReport = report;
}
public PersonalInfoBuilder()
{
}
public PersonalInfoBuilder NameIs(string name)
{
DeveloperReport.Name = name;
return this;
}
public PersonalInfoBuilder IDis(int id)
{
DeveloperReport.Id = id;
return this;
}
}
You only have to pass the report instance if you want to have both instances of DeveloperReportBuilder and PersonalInfoBuilder have acces to the same instance of DeveloperReport.
Inheritance will not copy the instance values.

Interface with a list as property

I want to implement an interface that's quite simple :
public interface IProfession
{
List<string> jobSkills { get; set; }
void setSkills();
}
public class artisan : IProfession
{
int money = 1200;
public List<string> jobSkills;
public void setSkills(){
jobSkills.Add("baratin");
jobSkills.Add("marchandage");
jobSkills.Add("monde_naturel");
jobSkills.Add("royaume_natal");
jobSkills.Add("sagacite");
jobSkills.Add("statut");
jobSkills.Add("statut");
}
}
Vstudio tells me that Models.artisan does not implement interface member Models.IProfession.jobSkills.
Why? I have tried this too :
public class artisan : IProfession
{
int money = 1200;
protected List<string> jobSkills;
public List<string> _jobSkills
{
get { return jobSkills;}
set { jobSkills = value; }
}
public void setSkills(){
jobSkills.Add("baratin");
jobSkills.Add("marchandage");
jobSkills.Add("monde_naturel");
jobSkills.Add("royaume_natal");
jobSkills.Add("sagacite");
jobSkills.Add("statut");
jobSkills.Add("statut");
}
}
but it does not work either (same error). can someone explain what I'm missing?
Thank you
Your interface requires a property jobSkills. You will need to implement a property then:
public interface IProfession
{
List<string> JobSkills { get; set; }
void SetSkills();
}
public class Artisan : IProfession
{
public List<string> JobSkills { get; set; };
public void SetSkills()
{
}
}
You need
public List<string> jobSkills { get; set; }
Also in your method you need to initialize the list.
public void setSkills()
{
if(jobSkills == null)
jobSkills = new List<string>();
jobSkills.Add("baratin");
jobSkills.Add("marchandage");
jobSkills.Add("monde_naturel");
jobSkills.Add("royaume_natal");
jobSkills.Add("sagacite");
jobSkills.Add("statut");
jobSkills.Add("statut");
}

Remove flexible Postfixes to allow AutoMapper to match the properties without ForMember

The problem is that we have more than thousend database tables with properties that have a dynamic postfix (e.g. properties like: Name_A1234, Name_B4567, Name_H123). Now we want to use AutoMapper to map this properties to DataModels with properties without this postfixes. The solution with the ForMember function is to time expansive and also produces too much code.
I've tried the following to solve this issue:
public class A
{
public string Name_XY1234 { get; set; }
}
public class B
{
public string Name_AB1234 { get; set; }
}
public class C
{
public string Name { get; set; }
}
public class MyNamingConvention : INamingConvention
{
private readonly Regex _splittingExpression = new Regex(#"\A[a-zA-Z0-9]+(?=_?.*)");
public string SeparatorCharacter
{
get { return string.Empty; }
}
public System.Text.RegularExpressions.Regex SplittingExpression
{
get { return _splittingExpression; }
}
}
public class Test
{
public Test()
{
try
{
Mapper.Initialize(cfg =>
{
cfg.SourceMemberNamingConvention = new MyNamingConvention();
cfg.DestinationMemberNamingConvention = new MyNamingConvention();
});
AutoMapper.Mapper.CreateMap<A, C>();
var a = new A();
a.Name_XY1234 = "Test";
var c = AutoMapper.Mapper.Map<C>(a);
// should be Test...
System.Diagnostics.Debug.WriteLine(c.Name);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
Unfortunately this doesn't work.
How can I solve this issue?
Thank you.

TDD - Why does this Assert.AreSame pass?

I have a test method...
[TestMethod]
public void MainViewModel_PropertiesReflectDataEntityProperties()
{
// Arrange
var facilityDataEntity = MockRepository.GenerateStub<FacilityDataEntity>();
var shopOrderDataEntity = MockRepository.GenerateStub<ShopOrderDataEntity>();
// Act
MainViewModel mainViewModel = new MainViewModel(facilityDataEntity, shopOrderDataEntity);
// Assert
Assert.AreSame(facilityDataEntity.Value, mainViewModel.FacilityValue);
}
... and the test passes. However, I have not implemented the mapping of the DataEntity's properties to the MainViewModel's properties yet! How can this be? I thought AreSame checks whether two references point to the same instance.
public class MainViewModel
{
private readonly FacilityDataEntity facilityDataEntity;
private readonly ShopOrderDataEntity shopOrderDataEntity;
public MainViewModel(FacilityDataEntity facilityDataEntity)
{
this.facilityDataEntity = facilityDataEntity;
}
public MainViewModel(FacilityDataEntity facilityDataEntity, ShopOrderDataEntity shopOrderDataEntity)
{
this.facilityDataEntity = facilityDataEntity;
this.shopOrderDataEntity = shopOrderDataEntity;
}
public ShopOrderDataEntity ShopOrderDataEntity
{
get { return shopOrderDataEntity; }
}
public FacilityDataEntity FacilityDataEntity
{
get { return facilityDataEntity; }
}
public int ShopOrder { get; set; }
public decimal RequiredQuantity { get; set; }
public string ItemCode { get; set; }
public string ItemDescription { get; set; }
public string FacilityValue { get; set; }
public string FacilityLabel { get; set; }
public static IEnumerable<MainViewModel> TranslateDataEntityList(IEnumerable<FacilityDataEntity> facilityDataEntityList)
{
foreach (FacilityDataEntity facilityDataEntity in facilityDataEntityList)
{
yield return new MainViewModel(facilityDataEntity);
}
}
public static IEnumerable<MainViewModel> TranslateDataEntityList(FacilityDataEntity facilityDataEntity, IEnumerable<ShopOrderDataEntity> shopOrderDataEntityList)
{
foreach (ShopOrderDataEntity shopOrderDataEntity in shopOrderDataEntityList)
{
yield return new MainViewModel(facilityDataEntity, shopOrderDataEntity);
}
}
}
Underneath it all, these tests are just using Object.ReferenceEquals:
true if objA is the same instance as objB or if both are null; otherwise, false.
I guess this is happening because they are both null.
in this case, I'd say its comparing null with null, which are the same.

List a classes generic interface names

I have this c# code;
case "Cafe":
source.trendItem = new TrendingLocation<ITrendingCafe>();
break;
case "Pub":
source.trendItem = new TrendingLocation<ITrendingPub>();
break;
etc
a trendItem is defined like this;
public class TrendingItem<T> where T : ITrendingItem
{
public T trendItem { get; set; }
}
Then I have this;
public List<TrendingItem<ITrendingItem>> trendItems { get; set; }
Now for each item in the above trendItems i want to get the interfaces.
I tried using;
string g = fvm.trendItems[4].trendItem.GetType().GetInterfaces()[1].Name;
and
string g = typeof(TrendingLocation<>).GetInterfaces()[0].Name;
but neither of these lists the Generic interface such as ITrendingCafe, ITrendingRestaurant etc.
Is there a way I can get the name of the generic interface name?
You want to use the Type's GetGenericArguments method.
If I understand your structure, it will be something like:
Type[] typeArguments = fvm.trendItems[4].trendItem.GetType().GetGenericArguments();
foreach (Type tParam in typeArguments)
{
// Compare the type with the interface you are looking for.
}
I take it that ITrendingCafe is an interface that implements ITrendingItem. I wrote a quick program that takes and displays all of the interfaces that T Implements:
using System;
using System.Collections.Generic;
namespace TestConsoleApplication
{
public interface ITrendingItem
{
string ItemName { get; set; }
}
public interface ITrendingCafe : ITrendingItem
{
string CafeName { get; set; }
}
public class TrendingItem<T> where T : ITrendingItem
{
public T trendItem { get; set; }
}
public class Cafe : ITrendingCafe
{
public string ItemName { get; set; }
public string CafeName { get; set; }
}
class Program
{
static void Main(string[] args)
{
var test = new List<TrendingItem<ITrendingItem>> { new TrendingItem<ITrendingItem> { trendItem = new Cafe() } };
foreach (var trendingItem in test[0].trendItem.GetType().GetInterfaces())
{
Console.Out.WriteLine(trendingItem.Name);
}
Console.ReadKey();
}
}
}
And here is the output:
As you can see, the interface is there. Just loop through and find the one you need!

Categories