C# conditional based on property [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following classes
class ClassA : SuperClass { }
class ClassB : SuperClass { }
class ClassC : SuperClass { }
class SuperClass
{
int Id { get; set; }
string Property1 { get; set; }
string Property2 { get; set; }
List<string> Property3 { get; set; }
}
When a condition is met, I have to override one, two or all of the properties in any of the classes (A, B, C) and I have to know that the properties were overridden and which ones where.
So I created this interface that should be implemented by SuperClass.
public interface IOverride
{
string OverrideProperty1 { get; set; }
string OverrideProperty2 { get; set; }
List<string> OrderedProperty3 { get; set; }
}
How can I know if a property was overridden without having to create a boolean for each property.
Or should I go for a different approach?
EDIT
ClassA, ClassB and ClassC data come from a specific source and for each of the objects I get information from another source. If the new source has values I need to stored them and override the original ones.
Something like
var dataList = GetClassesData() as List<SuperClass>;
var newData = GetNewData() as object[];
foreach (var data in dataList)
{
if (newData.Contains(o => o.Id == data.Id))
{
data.Property1 = newData[Id].Property1;
data.Property2 = newData[Id].Property2;
data.Property3 = newData[Id].Property3;
}
}

Overriding itself is not intent to be conditional, what can be conditional, is the value of the property you return from overridden class.

This should do it for you.
if(typeof(ClassA).GetMethod("Property1").DeclaringType == typeof(SuperClass)){
//This method was overridden
}

If I understand your edited question right, you could put it like that:
public interface IOverride
{
string StandardProperty1 { get; set; }
string StandardProperty2 { get; set; }
List<string> StandardProperty3 { get; set; }
string OverrideProperty1 { get; set; }
string OverrideProperty2 { get; set; }
List<string> OrderedProperty3 { get; set; }
}
class ClassA : SuperClass { }
class ClassB : SuperClass { }
class ClassC : SuperClass { }
class SuperClass : IOverrideProperty
{
string StandardProperty1 { get; set; }
string StandardProperty2 { get; set; }
List<string> StandardProperty3 { get; set; }
string OverrideProperty1 { get; set; }
string OverrideProperty2 { get; set; }
List<string> OrderedProperty3 { get; set; }
string Property1
{
get
{
if (condition)
return OverrideProperty1;
else
return StandardProperty1;
}
set
{
if (condition)
OverrideProperty1 = value;
else
StandardProperty1 = value;
}
//Same for Property2 and 3
}
You can now set both Properties and your condition will decide wich one is returned or set.

Related

"If is class" Condition Failing [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 9 months ago.
Improve this question
Hi I have 3 base interfaces:
public interface IKlarfDefect
{
int TEST { get; set; }
int DEFECTID { get; set; }
}
public interface IKlarfDefect <TImageListInfo> : IKlarfDefect
{
List<TImageListInfo> KlarfImageList { get; set; }
}
public interface IHasKlarfImageList<TImageListInfo>
{
List<TImageListInfo> KlarfImageList { get; }
}
These classes implement it:
public class CIMKlarfDefect : IKlarfDefect, IHasKlarfImageList<CIMKlarfImageListInfo>
{
public int TEST { get; set; }
public int DEFECTID { get; set; }
public List<CIMKlarfImageListInfo> KlarfImageList { get; set; } = new List<CIMKlarfImageListInfo>();
}
public class RMTKlarfDefect : IKlarfDefect, IHasKlarfImageList<CIMKlarfImageListInfo>
{
public int TEST { get; set; }
public int DEFECTID { get; set; }
public List<RMTKlarfImageListInfo> KlarfImageList { get; set; } = new List<RMTKlarfImageListInfo>();
}
Then I have this function in another class that tries to read through these classes:
internal static string CreateCIMDefectListString(IEnumerable<IKlarfDefect<IKlarfImageListInfo>> klarfDefectList)
{
StringBuilder defectListString = new StringBuilder();
defectListString.AppendLine("");
foreach (var klarfDefect in klarfDefectList) {
defectListString.Append(klarfDefect.TEST).Append(" ");
defectListString.Append(klarfDefect.DEFECTID).Append(" ");
if (klarfDefect is IHasKlarfImageList<IKlarfImageListInfo> grcKlarfDefect)
{
if (grcKlarfDefect.KlarfImageList.Count == 0)
{
defectListString.Append("N;");
defectListString.AppendLine();
}
}
}
return defectListString.ToString();
}
It compiles but the if statement fails when I am passing in either RMTKlarfDefect or CIMKlarfDefect. Might anyone know why this is?
if klarfDefect is IHasKlarfImageList grcKlarfDefect
fails as in, it doesn't return true which would allow it to process the imagelist
Your if statement says
if (klarfDefect is IHasKlarfImageList<IKlarfImageListInfo> grcKlarfDefect)
But your classes implement
IHasKlarfImageList<CIMKlarfImageListInfo>
So you need to update your if statement accordingly:
if (klarfDefect is IHasKlarfImageList<CIMKlarfImageListInfo> grcKlarfDefect)

Set interface us a properties c#

I've created three interfaces - IUser, ICostCenter, IDepartment. IUser and IDepartment are properties of ICostCenter.
public interface ICostCenter
{
IDepartment Department { get; set; }
User.IUser CostCenterHead { get; set; }
}
The class implementing ICostCenter will be used in the DbContext for my db.
public class tblCostCenter : WorkingInterface.Interface.Organization.ICostCenter
{
public tblCostCenter()
{
this.ID = Guid.NewGuid().ToString();
}
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
private WorkingInterface.Interface.User.IUser CostCenterHead { get; set; }
public string UserID { get; set; }
[ForeignKey("UserID")]
public Model.tblUser UserObject
{
get { return (Model.tblUser)this.CostCenterHead; }
set { this.CostCenterHead = value; }
}
private WorkingInterface.Interface.Organization.IDepartment Department { get; set; }
public string DepartmenID { get; set; }
[ForeignKey("DepartmenID")]
public Model.tblDepartment DepartmentObject
{
get { return (Model.tblDepartment)this.Department; }
set { this.Department = (Model.tblDepartment)value; }
}
}
I'm getting an error because I made the IUser and IDepartment properties private. How can I properly implement the interface? I want these properties to be hidden.
The interface is declared explicitly as public, that means that all the members declared in that interface MUST be public
So you need to declare both of these properties as public:
public WorkingInterface.Interface.User.IUser CostCenterHead { get; set; }
public WorkingInterface.Interface.Organization.IDepartment Department { get; set; }
NOTE: these have been declared as implicit implementations, so they are available to all contexts. If you want to hide them from general use, you can use explicit implementation.
Because you tried to use private accessibility, I assume you generally want to hide these properties from view, you can do this and still honor the interface contract by using explicit implementation syntax:
WorkingInterface.Interface.User.IUser ICostCenter.CostCenterHead { get; set; }
WorkingInterface.Interface.Organization.IDepartment ICostCenter.Department { get; set; }
They are still public but can only be accessed by first casting the object to the specific interface type explicitly.
tblCostCenter obj = new tblCostCenter();
...
// this wont work:
Console.WriteLine(obj.CostCenterHead);
// instead you will have to cast the object first
Console.WriteLine((obj as ICostCenter)).CostCenterHead);
// or if the local variable was an ICostCenter
ICostCenter costObj = obj;
Console.WriteLine(costObj.CostCenterHead);
...
// Pattern matching can also be helpful in these scenarios
if (obj is ICostCenter cc)
Console.WriteLine(cc.CostCenterHead);
If you want to use explicit declaration in your class you could try this:
WorkingInterface.Interface.User.IUser ICostCenter.CostCenterHead { get; set; }
public string UserID { get; set; }
[ForeignKey("UserID")]
public Model.tblUser UserObject
{
get { return ((ICostCenter)this).CostCenterHead as Model.tblUser; }
set { ((ICostCenter)this).CostCenterHead = value; }
}
WorkingInterface.Interface.Organization.IDepartment ICostCenter.Department { get; set; }
public string DepartmenID { get; set; }
[ForeignKey("DepartmenID")]
public Model.tblDepartment DepartmentObject
{
get { return ((ICostCenter)this).Department as Model.tblDepartment; }
set { ((ICostCenter)this).Department = value; }
}
this only works if:
Model.tblDepartment : IDepartment
Model.tblUser : User.IUser

Interface with a list of interface, how to choose one type implemented by interface

This is my first question on StackOverflow, so please forgive and tell me if I'm doing something wrong.
Problem:
I write some kind of dictionary connected to DB and text files etc. nothing commercial, just learning. For better explanation it can be English-French.
I want to refactor the code to have possibility of use one "general" method to process entrance for English-French and French-English dictionary model. On the begining i made separate model for each of them(I will paste if necessary) and now i would like to make everything "universal". What I did till i stop:
public interface IWordModel
{
int Id { get; set; }
string Name { get; set; }
string Definition { get; set; }
}
class implementing IWordModel:
public class EnglishWordModel: IWordModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Definition { get; set; } = null;
}
public class FrenchWordModel : IWordModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Definition { get; set; } = null;
}
Interface implementing IWordModel and problematic List of this interface:
public interface IDictionairyModel<T> where T : IWordModel
{
int Id { get; set; }
T BaseWord { get; set; }
List<T> DerivativeWords { get; set; }
}
Class implementing IDicionairyModel
public class EnglishFrenchDictionairyModel<T>: IDictionairyModel where T : IWordModel
{
public int Id { get; set; }
public IWordModel BaseWord { get; set; } = new EnglishWordModel();
public List<IWordModel> DerivativeWords { get; set; } = = new
List<IWordModel>(new List<FrenchWordModel>());
}
public class FrenchDictionairyModel: IDictionairyModel<T> where T : IWordModel
{
public int Id { get; set; }
public IWordModel BaseWord { get; set; } = new FrenchWordModel();
public List<IWordModel> DerivativeWords { get; set; } = = new
List<IWordModel>(new List<EnglishWordModel>());
}
And my Question
How to make that i.e in FrenchDictionairyModel instance we will be able to define BaseWord only as FrenchWordModel and add to DerivativeWords list ONLY EnglishWordModel? I know it have something common with covariance and contrvariance but i dont have idea how to apply this here.
Is it above code have some sense from experienced coder point of view or it's look like OK only in my head? If answer is NO then how it should look like, what pattern should i use?
How to use it properly in other methods? As now i was using i.e
public List<EnglishFrenchDictionairyModel>
CreateEnglishFrenchEntrance(List<EnglishFrenchDictionairyModel> model){
( ... )}
but its already showing "Using generic type requires 1 type arguments".
Thanks and have a Great Day!
It sounds like you need two generic parameters - one to apply to BaseWord and one to apply to DerivativeWords:
public interface IDictionairyModel<T,U>
where T : IWordModel, U : IWordModel
{
int Id { get; set; }
T BaseWord { get; set; }
List<U> DerivativeWords { get; set; }
}
Then define your FrenchDictionaryModel as so:
public class FrenchDictionairyModel:
IDictionairyModel<FrenchWordModel, EnglishWordModel>
{
public int Id { get; set; }
public FrenchWordModel BaseWord { get; set; } = new FrenchWordModel();
public List<EnglishWordModel> DerivativeWords { get; set; } = new List<EnglishWordModel>();
}
Thanks D Stanley! it works fine, just need to add two where clauses for U and T like:
public interface IDictionairyModel<T,U>
where T : IWordModel,
where U : IWordModel {(...)}
But now i have another issue which i would like to implement here.
For example i would like to create some method which will be remove duplicates from List but i want to this to be ONE method for all class which implementing IDictionairyModel
public static List<IDictionairyModel<IWordModel, IWordModel>> RemoveDuplicates(this List<IDictionairyModel<IWordModel, IWordModel>> model)
{
(...) return model;
}
What I need to do to be able to use this extension method on
List<FrenchDictionairyModel> model = new List<FrenchDictionairymodel>();
model.RemoveDuplicates();
As for now it return error.
Should I make FrenchDictionairyModel also generic like:
public class PoznanPolishDictionairyModel<T,U> : IDictionairyModel<PoznanWordModel, PolishWordModel>
where T:IWordModel
where U:IWordModel
??? What is the proper way
Thanks a lot!!!
Have a wonderful Sunday!
Best Regards

C# having Enums of Enums [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Assuming I have an enum category with some values:
enum Category {
ProgrammingBooks
CookingBooks
}
and I want each enum to have his own enum, for instance:
ProgrammingBooks will hold:
enum ProgrammingBooks {
CSharp,
Java,
Cpp
}
I saw a solution suggesting this:
enum Fauna {
enum Type { MAMMAL, BIRD }
TIGER(Type.MAMMAL),
LION(Type.MAMMAL),
PEACOCK(Type.BIRD),
OWL(Type.BIRD);
private final Type type;
Fauna(Type type) { this.type = type; }
}
with the usage:
Stream.of(Fauna.values()).filter(f -> f.type == BIRD).toList()
However, I'm just a beginner and I look for something that even if I do not know and should learn, wont go hardcore on me. I do not understand the example I mentioned (which I found on StackOverFlow).
Use classes or interfaces. For example:
public enum Category
{
ProgrammingBooks,
CookingBooks
}
public interface IBook
{
Category BookType { get; set; }
string Title { get; set; }
string Author { get; set; }
// ...
}
public class ProgrammingBook: IBook
{
public ProgrammingBook()
{
this.BookType = Category.ProgrammingBooks;
}
public string Author { get; set; }
public string Title { get; set; }
public Category BookType { get; set; }
// ...
}
public class CookBook : IBook
{
public CookBook()
{
this.BookType = Category.CookingBooks;
}
public string Author { get; set; }
public string Title { get; set; }
public Category BookType { get; set; }
// ...
}
If you want to support "sub-types" you could provide properties that only belong to a specific class and not into the interface because not every book is about programming. For example:
public enum ProgrammingLanguage
{
CSharp,
Java,
Cpp
}
public class ProgrammingBook: IBook
{
// a constructor that takes the ProgrammingLanguage as argument
public ProgrammingBook(ProgrammingLanguage language)
{
this.BookType = Category.ProgrammingBooks;
this.Language = language;
}
public ProgrammingLanguage Language { get; set; }
public string Author { get; set; }
public string Title { get; set; }
public Category BookType { get; set; }
// ...
}
Why i use interfaces at all? Because all books have something in common(f.e. they all have a title and an author). So you can benefit from Polymorphism:
var library = new List<IBook>();
var book1 = new ProgrammingBook(ProgrammingLanguage.CSharp) {Title = "C# in Depth", Author = "Jon Skeet"};
var book2 = new CookBook() { Title = "Everyday Superfood", Author= "Jamie Oliver" };
library.Add(book1);
library.Add(book2);
// now you can loop all and you know that all books have these properties
foreach (IBook book in library)
{
Console.WriteLine("Title: {0} Type: {1}", book.Title, book.BookType.ToString());
}
or if you only want to get programming-books:
foreach (IBook book in library.Where(b => b.BookType == Category.ProgrammingBooks))
{
// ...
}
the same with LINQ's Enumerable.OfType method which just checks the type:
foreach (IBook book in library.OfType<ProgrammingBook>())
{
// ....
}
Enum is just a representation of an integer with text. It cannot hold sub categories or anything but an integer.
You should create a class for the categories and hold an enum of the sub categories in each of them.
public class ProgrammingBook
{
public BookType Type{get;set;}
}
enum BookType {
CSharp,
Java,
Cpp
}

Value Cannot be null calculated model properties MVC 5 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have an model in my MVC application that contains som properties and som calculated properties. When i try to POST a new object of the model to database i get an error that my calculated properties cannot be null.
Here is my model:
public class OrderItem
{
public int orderItemId { get; set; }
[DataType(DataType.MultilineText)]
public string orderItemDescr { get; set; }
public string orderItemText { get; set; }
public double orderItemFixeedPrice { get; set; }
public virtual Order orderItemOrder { get; set; }
public virtual OrderItemType orderItemType { get; set; }
public virtual ICollection<Time> orderItemTime { get; set; }
public virtual ICollection<Material> orderItemMaterial { get; set; }
public OrderItem ()
{ }
public OrderItem (Order order)
{
this.orderItemOrder = order;
}
public string orderItemTypeDescr
{
get
{
return (this.orderItemType.orderItemTypeNumber.ToString() + " - " + orderItemDescr);
}
}
public double orderItemMaterialSum
{
get
{
return orderItemMaterial.Sum(m => m.materialItmPrice * m.materialItem);
}
}
public double orderItemTimeCount
{
get
{
return orderItemTime.Sum(t => t.timeItem);
}
}
public double orderItemTimeSum
{
get
{
return orderItemTime.Sum(t => t.timePrice * t.timeItem);
}
}
public double orderItemSum
{
get
{
return orderItemTimeSum + orderItemMaterialSum;
}
}
}
Error shows on properties: orderItemMaterialSum, orderItemTimeCount, orderItemTimeSum
these properties is only calculated as you seen and should not have values.
The problem comes only when i create an objekt and post it to database.
The reason for the error is that your properties in question are doubles and thus cannot be null. Three ways come to mind to address the problem:
Convert the properties in question to methods and re-factor your code
as necesesary.
Use a view model which only includes the properties you need (recommended)
Use the bind attribute to specify how binding is to be done when the model is posted (link)
Best practice is to use view models. Your view model might look something like the following:
public class OrderItemViewModel
{
public int orderItemId { get; set; }
[DataType(DataType.MultilineText)]
public string orderItemDescr { get; set; }
public string orderItemText { get; set; }
public double orderItemFixeedPrice { get; set; }
public virtual Order orderItemOrder { get; set; }
public virtual OrderItemType orderItemType { get; set; }
public virtual ICollection<Time> orderItemTime { get; set; }
public virtual ICollection<Material> orderItemMaterial { get; set; }
public string orderItemTypeDescr
{
get
{
return this.orderItemType.orderItemTypeNumber.ToString() + " - " + this.orderItemDescr;
}
}
}
Does this help?

Categories