So, I have 3 fields/properties. Say, they are, paramA, paramB, paramC. And I’ve three classes as Class A, Class B, Class C.
Requirement is to use:
• paramA, paramB in Class A
• paramA, paramC in Class B
• paramB, paramC in Class D
Is there any way to declare all these 3 properties in a common place and derive in the A,B,C classes as per the requirement....?
UPDATE
Please find some more details of the requirement:
The real requirement is:
There is a table ‘Que Table’ in database which is having following fields
• bool IsQb
• bool IsOverride
• string Identifier
• string userlogin
• FolderName
Following model classes are using for create/update/delete data in ‘Que Table’.
• CreateQue class
• UpdateQue class
• DeleteQue class
CreateQue class only requires the properties:IsQb, IsOverride,UserLogin, FolderName
UpdateQue class only requires the properties: IsQb, IsOverride, Identifier, UserLogin, FolderName
And DeleteQue class only requires: Identifier property.
The code for the model classes are:
public class CreateQue
{
public bool IsQb { get; set; }
public bool IsOverride { get; set; }
public string userlogin { get; set; }
public string FolderName { get; set; }
}
public class UpdateQue
{
public bool IsQb { get; set; }
public bool IsOverride { get; set; }
public string Identifier { get; set; }
public string userlogin { get; set; }
public string FolderName { get; set; }
}
public class DeleteQue
{
public string userlogin { get; set; }
public string Identifier { get; set; }
}
So, is there any pattern/architecture out there to declare all those properties in a single place and derive as per the requirement in those model classes....? Thanks in advance
It's a bit unclear what you need to do as we can't see your requirements. You could use interfaces:
public interface IHasPropertyA
{
string PropertyA { get; set; }
}
public interface IHasPropertyB
{
string PropertyB { get; set; }
}
public class ClassA : IHasPropertyA, IHasPropertyB
{
public string PropertyA { get; set; }
public string PropertyB { get; set; }
}
Related
On one hand I have a list of capabilities, for example:
public interface ICapability
{
public string Name { get; }
}
public class RangeCapability<T> : ICapability
{
public string Name { get; set; }
public T Min { get; set; }
public T Max { get; set; }
}
public class SetCapability<T>
{
public string Name { get; set; }
public HashSet<T> Set { get; set; }
}
On the other hand I have a list of requirements
public interface IRequirement
{
public string Name { get; }
}
public class Requirement<T> : IRequirement
{
public string Name { get; set; }
public T Value { get; set; }
}
Both capability list may contain capabilities of different types T and requirement list may contain requirements of different types. The important thing is that if for a given name the underlying types match I should check if value is between min and max (for range class) or in a set like in the example below:
public class Entity
{
List<ICapability> Capabilities { get; set; }
public bool IsSatisfying(List<IRequirement> requirements)
{
foreach(var requirement in requirements)
{
var capability = Capabilities.FirstOrDefault(x => x.Name == requirement .Name);
//how to check if here if types match and if req. within range or in collection?
}
}
}
I am not sure how to match generic types of two different classes and then do the check suitable for the apropriate implementation (is within range/is present in set). Can somebody point me in the right direction how could I make it work?
I believe this is what you're looking for. Make the interfaces generic and also make the Entity class generic.
public interface INamed<T>
{
string Name { get; }
}
public interface ICapability<T> : INamed<T>
{
}
public class RangeCapability<T> : ICapability<T>
{
public string Name { get; set; }
public T Min { get; set; }
public T Max { get; set; }
}
public class SetCapability<T>
{
public string Name { get; set; }
public HashSet<T> Set { get; set; }
}
public interface IRequirement<T> : INamed<T>
{
}
public class Requirement<T> : IRequirement<T>
{
public string Name { get; set; }
public T Value { get; set; }
}
public class Entity<T>
{
List<ICapability<T>> Capabilities { get; set; }
public bool IsSatisfying(List<IRequirement<T>> requirements)
{
foreach (var requirement in requirements)
{
var capability = Capabilities.FirstOrDefault(x => x.Name == requirement.Name);
//how to check if here if types match and if req. within range or in collection?
if(capability is INamed<T>)
{
Console.WriteLine("types match");
}
}
}
}
class HeroClass
{
skill1
skill2
}
class Batman : HeroClass
{
skill3
skill4
}
class Robin : HeroClass
{
skill3
skill4
skill5
}
I'm a beginner in programming.
I want to make a List which can hold different Types of Objects.
If i create a list of Type HeroClass I am not able to access specific properties of object Type Batman or Robin
How can this be done?
Another question: as you can see class Batman and Robin have equal properties (3/4) would it be better to let "Robin" inherit from class "Batman"? These properties are totally same(polymorphism wouldn't make any sense) Is this a code smell if to classes have exact same properties?
Thank you a lot!!
The first issue:
If i create a list of Type "HeroClass" i am not able to access specific properties of object Type "Batman" or "Robin"
You can access specific properties by casting object, for example:
var heroList = new List<HeroClass>();
heroList.Add(new Batman { skill3 = "skill3" });
heroList.Add(new Robin { skill5 = "skill5" });
Console.WriteLine(((Batman)heroList[0]).skill3);
Live demo here
The second issue:
These properties are totally same(polymorphism wouldn't make any sense) Is this a code smell if to classes have exact same properties?
Yes, you should use Interface Segregation Principle (ISP) of SOLID
That clients should not be forced to implement interfaces they don't use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one sub module
For example
interface IHero
{
string skill1 { get; set; }
string skill2 { get; set; }
}
interface IHero1234: IHero
{
string skill3 { get; set; }
string skill4 { get; set; }
}
interface IHero12345: IHero1234
{
string skill5 { get; set; }
}
class BaseHero : IHero
{
public string skill1 { get; set; }
public string skill2 { get; set; }
}
class Batman : IHero1234
{
public string skill1 { get; set; }
public string skill2 { get; set; }
public string skill3 { get; set; }
public string skill4 { get; set; }
}
class Robin : IHero12345
{
public string skill1 { get; set; }
public string skill2 { get; set; }
public string skill3 { get; set; }
public string skill4 { get; set; }
public string skill5 { get; set; }
}
Link live demo here
I am getting a rather weird casting error. Here is the code:
public class OrganizationLocation : IOrganizationLocation
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public interface IOrganizationLocation
{
string Name { get; }
}
public class Organization : IOrganization
{
public Guid Id { get; set; }
public string Alias { get; set; }
public virtual ICollection<OrganizationLocation> Location { get; set; }
public ICollection<IOrganizationLocation> Locations
{
get
{
return (ICollection<IOrganizationLocation>) Location;
}
}
}
public interface IOrganization
{
string Alias { get; }
ICollection<IOrganizationLocation> Locations { get; }
}
now when I try to run this via a service (backend data layer is EF6), the "Location" variable has all the values, however, the "Locations" variable fails to cast. If I try to do a safe cast, it comes back as null every time.
I'm not understanding why would the cast fail? It has same fields, both are ICollection Type, so why do I get a HashSet?
The reason why I am doing it this way is because for EF6 framework to be able to treat this class as a table it needs to have a concrete type and a public get/set. However, I do not wish to expose that, so I use interface instead and then inject the class when the interface is called. This way I only expose get method and on top of it I only expose interface layers.
Unable to cast object of type 'System.Collections.Generic.HashSet`1[Namespace.OrganizationLocation]' to type 'System.Collections.Generic.ICollection`1[Namespace2.IOrganizationLocation]'.
I was able to resolve this by changing the code to the following:
public class OrganizationLocation : IOrganizationLocation
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public interface IOrganizationLocation
{
string Name { get; }
}
public class Organization : IOrganization
{
public Guid Id { get; set; }
public string Alias { get; set; }
public virtual ICollection<OrganizationLocation> Location { get; set; }
public IEnumerable<IOrganizationLocation> Locations => Location
}
public interface IOrganization
{
string Alias { get; }
IEnumerable<IOrganizationLocation> Locations { get; }
}
I have an application that can contain a minimum of one "person" up to a maximum of fours "persons". I am using view models and manually mapping in the controller to the domain model.
I am completely lost as to how to include more than one "person" in the app. I've read up on using for but can't wrap my head around it.
Right now, I am just adding the data from the "person" class manually such that
Code:
public class SomeClass
{
public Guid SomeClassId {get; set;}
public string BorrowerFirst { get; set; }
public string BorrowerMI { get; set; }
public string BorrowerLast { get; set; }
public Suffix? BorrowerSuffix { get; set; }
... some more fields ...
}
and so on in the master class.
What I'd like to do is use a class such as:
Code:
public class Applicant
{
public string BorrowerFirst { get; set; }
public string BorrowerMI { get; set; }
public string BorrowerLast { get; set; }
public Suffix? BorrowerSuffix { get; set; }
}
can be reused in another class multiple times.
How can I separate that to strip that and instead use a named class consisting of first, middle and last names and allowing up to four "person" instances in my master class?
Have you tried inheritance?
public class Person
{
public Guid SomeClassId {get; set;}
public string BorrowerFirst { get; set; }
public string BorrowerMI { get; set; }
public string BorrowerLast { get; set; }
public Suffix? BorrowerSuffix { get; set; }
}
and the Applicant class:
public class Applicant : Person
{
//Only extra properties and methods here.
public string FullName
{
get
{
return this.BorrowerFirst + " " + this.BorrowerMI + " " + this.BorrowerLast;
}
}
}
You can then have a vendor as well:
public class Vendor: Person
{
//Only extra properties and methods here.
}
I have a problem while adding a new class in my existing structure. I am going to explain my problem as much clear as i can
public interface Imust
{
string Name { get; set; }
string File { get; set; }
string RowKey { get; set; }
string Time { get; set; }
string PartitionKey { get; set; }
}
public class TA : TableServiceEntity, Imust
{
public string Time { get; set; }
public string Name { get; set; }
public string File { get; set; }
}
public class TB : TableServiceEntity, Imust
{
public string Time { get; set; }
public string Name { get; set; }
public string File { get; set; }
}
public class TC : TableServiceEntity, Imust
{
public string Time { get; set; }
public string Name { get; set; }
public string File { get; set; }
}
public class _Table <T> : _Account where T : Imust
{
}
Here the above 3 classes are implemented as Tables and its properties as its columns in my project. Imust interface is implemented in each class because in generic class i put an interface constraint. TableServiceEntity class contains the implementation for RowKey and PartitionKey.And this class is also inherited in all 3 entities.
Problem : Now i have to add a new table in my application. So for this i have to add a new class here which is
public class TD : TableServiceEntity
{
}
I do not want this class to implement the Imust interface because it does not contain these columns. But i have to pass it as a parameter in generic class _Table.Because this new class has different columns but it perform same function which other 3 entities does. Now how will i add this new class while maintaining my existing structur ?
Please suggest me any better solution for this problem ?
EDIT
Yes i can put a constraint TableServiceEntity as a base class. But in generic class _Table there are few function which operate on File property like
public T AccessEntity(string Id = "0", string File = "0")
{
return (from e in ServiceContext.CreateQuery<T>(TableName)
where e.RowKey == Id || e.File == File
select e).FirstOrDefault();
}
If i removed this interface constraint then it shows an error that T does not have a defination for File.
I'd do this... the interface has no sense in your declaration as the more generic type for table is TableServiceEntity
public class _Table <T> : _Account where T : TableServiceEntity
{
}
Split the interface in two:
public interface Ibase
string RowKey { get; set; }
string PartitionKey { get; set; }
}
public interface Imust : Ibase
{
string Name { get; set; }
string File { get; set; }
string Time { get; set; }
}
public class TA : TableServiceEntity, Imust
{
public string Time { get; set; }
public string Name { get; set; }
public string File { get; set; }
}
public class TB : TableServiceEntity, Imust
{
public string Time { get; set; }
public string Name { get; set; }
public string File { get; set; }
}
public class TC : TableServiceEntity, Imust
{
public string Time { get; set; }
public string Name { get; set; }
public string File { get; set; }
}
public class _BaseTable <T> : _Account where T : Ibase
{
}
public class _Table <T> : _BaseTable<T> where T : Imust
{
}
And implement common functionality in _BaseTable and this specific to Time, Name and File in _Table.
It's even more intuitive after and edit you have made to your question. Thos methods in _BaseTable that rely on File, Name or Time can be marked abstract and overriden in _Table.
Updated to reflect posters additional info:
You need to specify a new Interface:
public interface IMust2 {
public string File {get;set;}
public string Rowkey {get;set;
}
Modify IMust to inherit from IMust2
public interface IMust : IMust2
{
public string Name {get;set;}
public string Time {get;set;}
public string PartitoinKey {get;set;}
}
Why not just have _Table be of <TableServiceEntity> type? Obviously, you are breaking your interface, so you can't keep using it as the generic as not every class will be of that interface?
You have 3 classes (TA, TB and TC) that are exactly the same. Why don't you have a single class, though?
For behavior (that is, methods), use a interface. For structure (that is, properties), use inheritance (like at TableServiceEntity).
Make TD inherit from the base class but do not implement the interface.
Change the restriction at _Table to be where T : TableServiceEntity
Regards