I'm pretty new with C# and .NET. I'm trying to model a graph with heterogeneous data. I mean i would like to be able to do something like this:
// Simple graph modeling using generics
public class Node<T>
{
private T data;
public Node(T data)
{
this.data = data;
}
}
public class Edge<T, U>
{
private T source;
private U destination;
public Edge(T source, U destination)
{
this.source = source;
this.destination = destination;
}
}
Building it this way:
Node<Person> p = new Node<Person>(new Person("Red John"));
Node<Computer> c = new Node<Computer>(new Computer("MyComputer"));
graph.AddNode(p);
graph.AddNode(c);
graph.AddEdge(new Edge<Person, Computer>(p, c));
But of course the graph class definition won't let me do this:
public class Graph<T> where T : CommonBaseClass
I've also tried defining a base class for both person and computer, but of course it's not working. Any help/idea suggestion? I need heterogeneous data because i have to merge list of different nodes.
Thanks for helping!
In cases like this, it can be convenient to have your generic classes derive from non-generic classes. That way, you can refer to all types of Nodes through a simple Node class:
public class Node
{
public Node(object data)
{
this.Data = obj;
}
public object Data { get; protected set; }
}
public class Node<T> : Node
{
public Node(T data) : base(data) { }
new public T Data
{
get { return (T)base.Data; }
}
}
If type object is too primitive, you can use generic constraints instead:
public class Node
{
public Node(IGraphData data)
{
this.Data = obj;
}
public IGraphData Data { get; protected set; }
}
public class Node<T> : Node where T : IGraphData
{
public Node(T data) : base(data) { }
new public T Data
{
get { return (T)base.Data; }
}
}
public class Edge
{
}
public class Edge<T, U> : Edge
where T : Node where U : Node
{
// ...
}
Now, your Graph class can allow any type of Node and Edge:
public class Graph
{
public void AddNode(Node node) { /* ... */ }
public void AddEdge(Edge edge) { /* ... */ }
}
You could use an interface (say IGraphItem) instead of a common base class, and have both Nodes and Edges implement IGraphItem.
Then Graph could be changed to:
public class Graph<T> where T : IGraphItem
Let me know if I've misunderstood the question, I'm not 100% sure this is what you were asking about...
Yoy can do this by interface
public interface INode
{
List<INode> Nodes { get; set; }
}
public class Person : INode
{
public List<INode> Nodes { get; set; }
private string _name;
public Person(string name)
{
_name = name;
}
}
public class Computer : INode
{
public List<INode> Nodes { get; set; }
private int _number;
public Computer(int number)
{
_number = number;
}
}
And use:
var person = new Person("P1");
var computer = new Computer(1);
person.Nodes.Add(computer);
computer.Nodes.Add(person);
Related
I have a singleton class, holding several list of data. I want to have a function to return one of the list based on the requested data type
public interface IRentable
{
long Id { get; set; }
}
public class Book : IRentable
{
private long _id;
public long Id
{
get { return _id; }
set { _id = value; }
}
public string Name { get; set; }
public int Pages { get; set; }
}
public class DVD : IRentable
{
private long _id;
public long Id
{
get { return _id; }
set { _id = value; }
}
public string Name { get; set; }
public TimeSpan Length { get; set; }
}
public class DBReferenceSingleton
{
private List<Book> _bookList;
private List<DVD> _dvdList;
public IEnumerable<Entity> GetEntities<Entity>() where Entity : IRentable
{
switch(typeof(Entity).Name)
{
case nameof(Book):
return _bookList;
case nameof(DVD):
return _dvdList;
}
return null;
}
This is not working, since a conversion is needed. I wonder if there is any elegant solution (without serialize all elements or implement IConvertible)?
Background: I was looking into the implementation of Repository pattern implementation from Microsoft document website and a couple of YouTube videos. Their base class implementations are bounded with DBContext,
[from Microsoft doc]
public class GenericRepository<TEntity> where TEntity : class
{
internal SchoolContext context;
internal DbSet<TEntity> dbSet;
[from youtube]
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
Context = context;
}
public IEnumerable<TEntity> GetAll()
{
return Context.Set<TEntity>().ToList();
}
So, this means this base class cannot be used for databases without EntityFramework. I'm trying to remove DBContext in my base class
public class InMemoryRepository<TEntity> : IRepository<TEntity> where TEntity : IRentable
{
private IEnumerable<TEntity> _entities;
public IEnumerable<TEntity> GetAll()
{
if (_entities == null)
{
_entities = DBReferenceSingleton.GetInstance.GetEntities<TEntity>();
}
return _entities;
}
public TEntity Get(long id)
{
GetAll();
if (_entities == null)
{
return default(TEntity);
}
return _entities.FirstOrDefault(t => t.Id == id);
}
(I was wrong in my previous code, as I was using "class" instead of "IRentable" as I thought it will be generic for all classes. After implementing the Get(long id) function. I found I have to have a IRentable interface so I made the changes. And the answer from The Lemon work perfectly.
Thanks
It doesn't look like generics seem the right tool here; not least because Book and DVD don't have a common base class.
I think you should have two methods:
public List<Book> GetBooks() => _bookList;
public List<DVD> GetDvds() => _dvdList;
Have you tried doing a Cast?
public class Book
{
public string Name { get; set; }
public int Pages { get; set; }
}
public class DVD
{
public string Name { get; set; }
public TimeSpan Length { get; set; }
}
public class DBReferenceSingleton
{
private List<Book> _bookList;
private List<DVD> _dvdList;
public IEnumerable<Entity> GetEntities<Entity>() where Entity : class
{
switch(typeof(Entity).Name)
{
case nameof(Book):
return _bookList as List<Entity>;
case nameof(DVD):
return _dvdList as List<Entity>;
}
return null;
}
}
the "as List< Entity >" will return null if the object is the wrong type, or the object as the type if it's the right type. The A = B as C pattern works for inherited types as well, just remember to check for null returned values for cases where your type isn't as well known as in this situation
A side comment on the usefulness of having a generic method in this case: In this method you're forced to set the type of entity each time explicitly, which means your method is functionally non-generic - so you might as well make two explicit methods.
One case where a generic method like the one you have might be more useful, is if book and dvd both inherited from a base class, and you had some follow up methods that needed to operate off a list of . For example, you might end up wanting to do something like this instead in your code:
public class Book : Rentable
{
public int Pages { get; set; }
}
public class DVD : Rentable
{
public TimeSpan Length { get; set; }
}
public class Rentable
{
public string Name { get; set; }
public string borrowedBy { get; set; }
}
public class DBReferenceSingleton
{
private List<Book> _bookList;
private List<DVD> _dvdList;
public enum RentableType { Book, DVD }
public IEnumerable<Rentable> GetEntities(RentableType entityType)
{
switch (entityType)
{
case RentableType.Book:
return _bookList.ToList<Rentable>();
case RentableType.DVD:
return _dvdList.ToList<Rentable>();
default:
throw new NotImplementedException($"Entity {entityType} not supported");
}
return null;
}
}
In my project i have 4 layers presentation,BL,DL, and dataObjects. i want to implement abstract factory pattern to get the object i want(doctor/Engineer). Is the code below implementing factory pattern?
public interface IProfessional //The Abstract Factory interface.
{
IProfession CreateObj();
}
// The Concrete Factory class1.
public class DocFactory : IProfessional
{
public IProfession CreateObj()
{
return new Doctor();
}
}
// The Concrete Factory class2.
public class EngFactory : IProfessional
{
public IProfession CreateObj()
{
// IMPLEMENT YOUR LOGIC
return new Engineer();
}
}
// The Abstract Item class
public interface IProfession
{
}
// The Item class.
public class Doctor : IProfession
{
public int MedicalSpecialty
{
get; set;
}
public int AreaofExpertise
{
get; set;
}
}
// The Item class.
public class Engineer : IProfession
{
public string Title{
get;set;
}
public int AreaofExpertise
{
get; set;
}
}
// The Client class.
public class AssignProfession
{
private IProfession _data;
public AssignProfession(DataType dataType)
{
IProfessional factory;
switch (dataType)
{
case DataType.Doc:
factory = new EngFactory();
_data = factory.CreateObj();//from here i will get engineer
break;
case DataType.Eng:
factory = new DocFactory();
_data = factory.CreateObj();//from here i will get doctor
break;
}
}
public IProfession GiveProfessional()
{
return _data;
}
}
//The DataType enumeration.
public enum DataType
{
Doc,
Eng
}
Your code does implement the pattern but not to the full extent which C# allows, in other words - you are not using the important benefits of the C# language.
Here is an example of how you can do it better:
class Program
{
static void Main(string[] args)
{
var myEngineer = ProfessionFactory.CreateProffession<Engineer>();
var myDoctor = ProfessionFactory.CreateProffession<Doctor>();
myEngineer.EnginerringStuff();
myDoctor.HealingPeople();
var myEngineer2 = (Engineer)ProfessionFactory.CreateProffession("Engineer");
//using the other method I still have to cast in order to access Engineer methods.
//therefore knowing what type to create is essential unless we don't care about engineer specific methods,
//in that case we can do:
var myEngineer3 = ProfessionFactory.CreateProffession("Engineer");
//which is useless unless we start involving reflections which will have its own price..
}
public interface IProfessionFactory
{
IProfession CreateObj();
}
public interface IProfession : IProfessionFactory
{
string ProfessionName { get; }
}
public abstract class ProfessionFactory : IProfessionFactory
{
public abstract IProfession CreateObj();
public static T CreateProffession<T>() where T:IProfessionFactory, new()
{
return (T)new T().CreateObj();
}
public static IProfession CreateProffession(object dataObj)
{
if (dataObj == "Engineer")
return CreateProffession<Engineer>();
if (dataObj == "Doctor")
return CreateProffession<Doctor>();
throw new Exception("Not Implemented!");
}
}
public class Engineer : IProfession
{
public string ProfessionName
{
get { return "Engineer"; }
}
public IProfession CreateObj()
{
return new Engineer();
}
public void EnginerringStuff()
{}
}
public class Doctor : IProfession
{
public string ProfessionName
{
get { return "Doctor"; }
}
public IProfession CreateObj()
{
return new Doctor();
}
public void HealingPeople()
{}
}
}
It does seem to have all elements of the pattern, however your IProfession is empty. I am going to assume that is just a placeholder and you are going to fill it in with some methods that represent a behavior that is common to all professions.
Contrast that with the example given in Allen Holub's book
He mentions Collection as the AbstractFactory, Iterator as the abstract product, Tree as the concrete factory and the iterators that are returned as concrete products.
I have a class that looks like:
public class InvokeProxy : MarshalRefByObject, IFace
{
public InvokeProxy(IFace face)
{
this.Face = face;
}
private IFace Face { get; set; }
public string Execute(string data)
{
return this.Face.Execute(data)
}
}
And I'm tasked with making it generic. Since I can't inherit from the generic class, I'm somewhat stuck, does anyone know a workaround?
I'm not really sure what you're looking to do by making InvokeProxy into InvokeProxy<T>...does this help?
public class InvokeProxy<T> : MarshalRefByObject, IFace where T : IFace
{
public InvokeProxy(T face)
{
this.Face = face;
}
private T Face { get; set; }
public string Execute(string data)
{
return this.Face.Execute(data);
}
}
Not really sure if I understood the question....
public class InvokeProxy<T> : MarshalRefByObject where T : class
{
public InvokeProxy(T face)
{
this.Face = face;
}
private T Face { get; set; }
public string Execute(string data)
{
return this.Face.Execute(data)
}
}
I'm implementing a type hierarchy using class table inheritance. However, I'm having trouble with the static methods returning the base type instead of the child type. I've found a way around this but it's not too pretty. Take the following classes
public class Entity : ActiveRecordBase<Entity> { }
public class Person : Entity {}
calling
Person.FindAll();
actually returns an Entity[] instead of a Person[]. I can get around this by implementing FindAll in all derived classes, but who wants to do that? I was also able to create a base class that all classes derive from and implement
public R[] FindAll<R>() {}
but I just don't like the look of
Person.FindAll<Person>()
Is there any way to be able to call FindAll() from the derived classes and actually get the derived classes instead of the base class?
That's how .net works: there's no polymorphism for static methods. You already found a couple of workarounds, another one is not to rely on these static methods inherited from ActiveRecordBase<T>, but instead use ActiveRecordMediator<T> directly.
Maybe you could do:
public class Entity<T> : ActiveRecordBase<T> { }
public class Person : Entity<Person> {}
That way FindAll() would return Person[]
Even the documentation of Castle.ActiveRecord uses the workaround that you found.
See here for a full example and some other solutions: http://docs.castleproject.org/Default.aspx?Page=Type%20hierarchy&NS=Active%20Record
I copied the code in case that site disappears.
Base class "Entity"
using Castle.ActiveRecord;
[ActiveRecord("entity"), JoinedBase]
public class Entity : ActiveRecordBase
{
private int id;
private string name;
private string type;
public Entity()
{
}
[PrimaryKey]
private int Id
{
get { return id; }
set { id = value; }
}
[Property]
public string Name
{
get { return name; }
set { name = value; }
}
[Property]
public string Type
{
get { return type; }
set { type = value; }
}
public static void DeleteAll()
{
DeleteAll(typeof(Entity));
}
public static Entity[] FindAll()
{
return (Entity[]) FindAll(typeof(Entity));
}
public static Entity Find(int id)
{
return (Entity) FindByPrimaryKey(typeof(Entity), id);
}
}
Derived classes "Person" and "Company"
using Castle.ActiveRecord;
[ActiveRecord("entitycompany")]
public class CompanyEntity : Entity
{
private byte company_type;
private int comp_id;
[JoinedKey("comp_id")]
public int CompId
{
get { return comp_id; }
set { comp_id = value; }
}
[Property("company_type")]
public byte CompanyType
{
get { return company_type; }
set { company_type = value; }
}
public new static void DeleteAll()
{
DeleteAll(typeof(CompanyEntity));
}
public new static CompanyEntity[] FindAll()
{
return (CompanyEntity[]) FindAll(typeof(CompanyEntity));
}
public new static CompanyEntity Find(int id)
{
return (CompanyEntity) FindByPrimaryKey(typeof(CompanyEntity), id);
}
}
[ActiveRecord("entityperson")]
public class PersonEntity : Entity
{
private int person_id;
[JoinedKey]
public int Person_Id
{
get { return person_id; }
set { person_id = value; }
}
public new static void DeleteAll()
{
DeleteAll(typeof(PersonEntity));
}
public new static PersonEntity[] FindAll()
{
return (PersonEntity[]) FindAll(typeof(PersonEntity));
}
public new static PersonEntity Find(int id)
{
return (PersonEntity) FindByPrimaryKey(typeof(PersonEntity), id);
}
}
The name is a little blurry, so here's the situation:
I'm writing code to use some 'trajectories'. The trajectories are an abstract thing, so I describe them with different interfaces. So I have a code as this:
namespace Trajectories {
public interface IInitial<Atom>
{
Atom Initial { get; set; }
}
public interface ICurrent<Atom>
{
Atom Current { get; set; }
}
public interface IPrevious<Atom>
{
Atom Previous { get; set; }
}
public interface ICount<Atom>
{
int Count { get; }
}
public interface IManualCount<Atom> : ICount<Atom>
{
int Count { get; set; }
}
...
}
Every concrete implementation of a trajectory will implement some of the above interfaces.
Here's a concrete implementation of a trajectory:
public class SimpleTrajectory<Atom> : IInitial<Atom>, ICurrent<Atom>, ICount<Atom> {
// ICount
public int Count { get; private set; }
// IInitial
private Atom initial;
public Atom Initial { get { return initial; } set { initial = current = value; Count = 1; } }
// ICurrent
private Atom current;
public Atom Current { get { return current; } set { current = value; Count++; } }
}
Now, I want to be able to deduce things about the trajectories, so, for example I want to support predicates about different properties of some trajectory:
namespace Conditions
{
public interface ICondition<Atom, Trajectory>
{
bool Test(ref Trajectory t);
}
public class CountLessThan<Atom, Trajectory> : ICondition<Atom, Trajectory>
where Trajectory : Trajectories.ICount<Atom>
{
public int Value { get; set; }
public CountLessThan() { }
public bool Test(ref Trajectory t)
{
return t.Count < Value;
}
}
public class CurrentNormLessThan<Trajectory> : ICondition<Complex, Trajectory>
where Trajectory : Trajectories.ICurrent<Complex>
{
public double Value { get; set; }
public CurrentNormLessThan() { }
public bool Test(ref Trajectory t)
{
return t.Current.Norm() < Value;
}
}
}
Now, here's the question: What if I wanted to implement AND predicate?
It would be something like this:
public class And<Atom, CondA, TrajectoryA, CondB, TrajectoryB, Trajectory> : ICondition<Atom, Trajectory>
where CondA : ICondition<Atom, TrajectoryA>
where TrajectoryA : // Some interfaces
where CondB : ICondition<Atom, TrajectoryB>
where TrajectoryB : // Some interfaces
where Trajectory : // MUST IMPLEMENT THE INTERFACES FOR TrajectoryA AND THE INTERFACES FOR TrajectoryB
{
public CondA A { get; set; }
public CondB B { get; set; }
public bool Test(ref Trajectory t) {
return A.Test(t) && B.Test(t);
}
}
How can I say: support only these trajectories, for which the arguments of AND are ok?
So I can be able to write:
var vand = new CountLessThan(32) & new CurrentNormLessThan(4.0);
I think if I create an overall interface for every subset of interfaces, I could be able to do it, but it will become quite ugly.
You could eliminate ICondition entirely and just use Predicates and functional style. Here's a sample static way to make one:-
public static Predicate<T> CountLessThan<T> (int value) where T:ICount
{
return (T item) => item.Count < value;
}
And here's how you might use it:-
Predicate<SimpleTrajectory> anded = x => CountLessThan<SimpleTrajectory>(5)(x) && CountLessThan<SimpleTrajectory>(3)(x);
You could also create extension methods like this to combine predicates:-
public static Predicate<T> And<T>(this Predicate<T> first, Predicate<T> second)
{
return (T item) => first(item) && second(item);
}
An alternative would be to have a base, abstract, generic Condition class from which your other conditions derive and then implement And, Or, ... in the base condition class allowing for a fluent interface like:-
... = new CountLessThan(5).And(new CountLessThan(3))
Being generic in T would ensure that you could only combine conditions that have the same T.