How to implement Master/Detail classes using Generics and inheritance [duplicate] - c#

This question already has answers here:
Casting List<T> - covariance/contravariance problem
(3 answers)
Closed 5 years ago.
I am writing the base classes for a Data Model using Generics. The base classes should support:
DetailClass with DetailKey (any type)
MasterClass with MasterKey (any type) and holding a List<DetailClass>
I would like to inherit from these 2 classes, whenever I have a Master/Detail relationship in my DM.
Here is the simplified code for the base classes:
class Master<TMKey, TDKey> {
public readonly TMKey MKey;
public readonly List<Detail<TMKey, TDKey>> Details;
public Master(TMKey mKey) {
MKey = mKey;
Details = new List<Detail<TMKey, TDKey>>();
}
}
class Detail<TMKey, TDKey> {
public readonly TDKey DKey;
public readonly Master<TMKey, TDKey> Master;
public Detail(TDKey dKey, Master<TMKey, TDKey> master) {
DKey = dKey;
Master = master;
}
}
I run into troubles with the compiler, when I try to inherit from these classes:
class Sub: Detail<int, DateTime> {
public DateTime Date { get { return DKey; } }
public string S;
public Main main { get { return (Main)Master; } }
public Sub(DateTime date, string s, Main main) : base(date, main) {
S = s;
}
}
class Main: Master<int, DateTime> {
public int MainId { get { return MKey; } }
public string M;
public List<Sub> SubDetails { get { return (List<Sub>)Details; } } //compiler error
public Main(int mKey, string m) : base(mKey) {
M = m;
}
}
Compiler Error:
Cannot convert type 'System.Collections.Generic.List<FlatFileStore.Detail<int, System.DateTime>>' to 'System.Collections.Generic.List<FlatFileStore.Sub>'
It seems the compiler doesn't realise:
Sub: Detail<int, DateTime>
Any suggestion how to work around this compiler limitation ?
How needs the DM classes be changed to avoid any compiler problems and achieve high performance (i.e. no copies of collections) ?
A working sample code would be appreciated.
Edit1: It is not possible to use a .ToList() solution (see answer below). There might be thousands of details, .ToList() could get called thousands of times and each time would create a new List with thousands of items.
Edit2: The original question seemed to be a duplicate of "Casting List - covariance/contravariance problem", so I rewrote it to explain better. The other question asks specifically how to make a copy of List and therefore all answers in that question answer how to make such a copy. My question now asks how the classes have to be designed to avoid the compiler problem without using copying with its huge performance problems. There are other solutions possible, like using IReadOnlyList<T>, which are not mentioned at all in the answers in that question. But there might be also other possibilities, like telling the Master class which Type to use for the collection it creates. Or another design might be possible. Or ...

This is to do with co/contravariance. One way around this is to cast using linq:
public List<Sub> SubDetails { get { return Details.Cast<Sub>().ToList(); } }
Other solutions and discussion are shown here: Casting List<T> - covariance/contravariance problem

Related

Read only list of lists c#

In general terms, a program I'm making involves storing a small number of entries (probably less than 30 at any given time) which can be categorized. I want to allow these entries to be seen but not altered from outside the class using them. I made a class called Entry which could be modified and another called ReadOnlyEntry which is a wrapper for an Entry object. The easiest way to organize these Entry objects it seems is to create a List<List<Entry>>, where each List<Entry> is a category. But then exposing that data in a readonly way became messy and complicated. I realized I would have to have one object of each of the following types:
List<List<Entry>> data;
List<List<ReadOnlyEntry>> // Where each ReadOnlyEntry is a wrapper for the Entry in the same list and at the same index as its Entry object.
List<IReadOnlyCollection<ReadOnlyEntry>> // Where each IReadOnlyCollection is a wrapper for the List<ReadOnlyEntry> at the same index in data.
IReadOnlyCollection<IReadOnlyCollection<ReadOnlyList>> readOnlyList // Which is a wrapper for the first item I listed.
The last item in the list would be exposed as public. The first lets me change entries, the second lets me add or delete entries, and the third lets me add or delete categories. I would have to keep these wrappers accurate whenever the data changes. This seems convoluted to me, so I'm wondering if there's a blatantly better way to handle this.
Edit 1:
To clarify, I know how to use List.asReadOnly(), and the stuff I proposed doing above will solve my problem. I'm just interested in hearing a better solution. Let me give you some code.
class Database
{
// Everything I described above takes place here.
// The data will be readable by this property:
public IReadOnlyCollection<IReadOnlyCollection<ReadOnlyList>> Data
{
get
{
return readOnlyList;
}
}
// These methods will be used to modify the data.
public void AddEntry(stuff);
public void DeleteEntry(index);
public void MoveEntry(to another category);
public void AddCategory(stuff);
public void DeleteCategory(index);
}
You can use List<T>.AsReadOnly() to return ReadOnlyCollection<T>.
Also, you're torturing the List<T> class storing the data the way you are. Build your own hierarchy of classes which store your individual lists.
.NET collections should support covariance, but they don't support it themselves (instead some interfaces support covariance https://msdn.microsoft.com/ru-ru/library/dd233059.aspx). Covariance means List<Conctrete> behaves like subclass of List<Base> if Concrete is subclass of Base. You can use interfaces covariation or just use casting like this:
using System.Collections.Generic;
namespace MyApp
{
interface IEntry
{
}
class Entry : IEntry
{
}
class Program
{
private List<List<Entry>> _matrix = null;
public List<List<IEntry>> MatrixWithROElements
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry));
}
}
public IReadOnlyList<List<IEntry>> MatrixWithRONumberOfRows
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry));
}
}
public List<IReadOnlyList<IEntry>> MatrixWithRONumberOfColumns
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry) as IReadOnlyList<IEntry>);
}
}
public IReadOnlyList<IReadOnlyList<IEntry>> MatrixWithRONumberOfRowsAndColumns
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry));
}
}
public void Main(string[] args)
{
}
}
}
Thanks to Matthew Watson for pointing on errors in my previous answer version.
You could make an interface for Entry which contains only getters; you would expose elements via this interface to provide read-only access:
public interface IEntry
{
int Value { get; }
}
The writable implementation would be simply:
public sealed class Entry : IEntry
{
public int Value { get; set; }
}
Now you can take advantage of the fact that you can return a List<List<Entry>> as a IReadOnlyCollection<IReadOnlyCollection<IEntry>> without having to do any extra work:
public sealed class Database
{
private readonly List<List<Entry>> _list = new List<List<Entry>>();
public Database()
{
// Create your list of lists.
List<Entry> innerList = new List<Entry>
{
new Entry {Value = 1},
new Entry {Value = 2}
};
_list.Add(innerList);
}
public IReadOnlyCollection<IReadOnlyCollection<IEntry>> Data => _list;
}
Note how simple the implementation of the Data property is.
If you need to add new properties to IEntry you would also have to add them to Entry, but you wouldn't need to change the Database class.
If you're using C#5 or earlier, Data would look like this:
public IReadOnlyCollection<IReadOnlyCollection<IEntry>> Data
{
get { return _list; }
}

Instantiate a class to call a method or use static methods? [duplicate]

This question already has answers here:
C# static vs instance methods
(8 answers)
Closed 6 years ago.
Let's say I have a class
public class product
{
public string GetName()
{
return "product";
}
public static string GetStaticName()
{
return "product";
}
}
These methods do the same thing but one is static and one isn't.
When i call these method I do this:
product p = new product();
string _ProductName = p.GetName();
and
string _ProductName = product.GetStaticName();
Which method is the best to use for performance etc?
Which method is the best to use for performance etc?
You haven't to address any performance issue here. You just have to decide if this method should be the same for all the instances of the objects you create. If the answer is yes, then it should be a static method. Otherwise, it should be an instance method. It's a design decision, not a performance decision.
By the way, based on your code. I don't think that in this case you have to address even that. You just want to get the name of the product and probably set it. That being said the following is the only thing you need.
public class Product
{
public string Name { get; set; }
}

Is it architecturally wrong to use dynamic return type on a method exposed through interface? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have a method that is exposed using interface in the business logic layer. It is as follows:
public interface IMyWorkingClass
{
IEnumerable<dynamic> GetSomeList();
}
public class MyWorkingClass : IMyWorkingClass
{
public IEnumerable<dynamic> GetSomeList()
{
dynamic foos = new List<dynamic>();
dynamic item = new ExpandoObject();
item.PropOne = (new Foo()).FooPropertyOne;
item.PropTwo = (new Bar()).BarPropertyOne;
foos.Add(item);
return foos;
}
}
public class Foo
{
public int FooId{get;set;}
public string FooPropertyOne{get;set;}
public string FooPropertyTwo{get;set;}
}
public class Bar
{
public int BarId{get;set;}
public string BarPropertyOne{get;set;}
public string BarPropertyTwo{get;set;}
}
There are a lot of different opinions/preferences out there about dynamic itself. I find them useful. One of my friends said dynamics are good but the way they are used above are not. The argument presented was that the compiler wont catch the things changed on dynamic object. I think the unit tests will be able to catch those. So I disagreed. What is your expert opinion? Thanks in advance :)
Update
Here's bit clearer (hopefully) code:
public interface IMyWorkingClass
{
IEnumerable<dynamic> GetListOfClassesForStudentDynamicReturn();
IEnumerable<StudentClassInfo> GetListOfClassesForStudentStaticReturn();
}
public class MyWorkingClass : IMyWorkingClass
{
public IEnumerable<dynamic> GetListOfClassesForStudentDynamicReturn(Student student)
{
dynamic listOfClasses = new List<dynamic>();
// repository pattern is used in DAL
var datafromDB = (StudentCollegeClassRepo.GetQueryable(x=>x.StudentId==student.StudentId)
.select(item => new {
item.CollegeClassId
,item.CollegeClass.CollegeClassName
,item.IsEnabledForStudent
}).ToList();
foreach (var item in datafromDB)
{
dynamic classWithStudent = new ExpandoObject();
classWithStudent.CollegeClassId = item.CollegeClassId;
classWithStudent.CollegeClassName = item.CollegeClassName;
classWithStudent.IsEnabledForStudent = item.IsEnabledForStudent;
listOfClasses.Add(studentWithClass);
}
return listOfClasses;
}
public IEnumerable<StudentClassInfo> GetListOfClassesForStudentStaticReturn(Student student)
{
// repository pattern is used in DAL
var datafromDB = (StudentCollegeClassRepo.GetQueryable(x=>x.StudentId==student.StudentId)
.select(item => new StudentClassInfo {
CollegeClassId = item.CollegeClassId
,CollegeClassName = item.CollegeClass.CollegeClassName
,IsEnabledForStudent = item.IsEnabledForStudent
}).ToList();
return datafromDB;
}
}
// this class is like a viewmodel
public class StudentClassInfo
{
public int CollegeClassId { get; set; }
public string CollegeClassName { get; set; }
public bool IsEnabledForStudent { get; set; }
}
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
}
public class StudentCollegeClass
{
public int StudentId { get; set; }
public int CollegeClassId { get; set; }
public bool IsEnabledForStudent { get; set; }
}
public class CollegeClass
{
public int CollegeClassId { get; set; }
public string CollegeClassName { get; set; }
}
Hopefully I made things little clearer now. So,method with dynamic return is ok or create a static type and have that returned instead? I am also learning how to ask question properly here.. Thanks for your patience and awesome replies :)
Despite what Skeet says :) I'll add some thoughts here.
If you start down the path of using Dynamics, you must shift your thinking. You don't know what your object is, you only care about what it can do.
You find yourself not needing interfaces rather quickly - and then you ask yourself "WTF am I doing anyway?". Which is always a great question to ask.
And then a shift happens as you start writing more tests to cover up the loss of a compiler check - you start writing methods a bit more clearly. You start relying on Factories and other classes to impose logic on top of these little bits of amorphous dynamic goo.
It's incredibly freeing if you consider the mental shift. For instance you have a "MyWorkingClass" that does something on top of Foo/Bar. If that was a fulfillment class called "Warehouse" that had some methods called "CheckInvetoryOf(dynamic item)" - things start to make a bit more sense.
In the real world you would send in an interface here - probably ITrackable or something - that exposes a very very small subset of what could be used. It would work, but what if you changed your approach later and wanted the Warehouse to ship digital goods - something like downloads?
Your Warehouse class was probably fashioned after a brick and mortar - and making the shift to sending out digital downloads... OH NO!
But if you use dynamics - it's easy. You could simply ask if the item has is an IDigitalGood (for instance) and handle it nicely.
So - the code you wrote is, yes, confusing. If you spend some time with Dynamic languages it will afford you the mental shift to make it not so confusing.
Oh - in terms of "Architecturally Wrong" to do what you did... who knows. If it's confusing, that's not good. If it makes testing hard - that's triple not good. If you get laughed at, you might be on the right track :)
So, you want to create an interface that expose a method that return an unknown IEnumerable? Is there a direct advantage in using the generic version of IEnumerble in this case beside saving some cast/test/overload that you would have to do anyway if you want to use those objects after the method is returned?
While I won't dispute that dynamic can be useful in some case. In my opinion, it often displays a design flaw. Every time I came to use it, I actually sat down and thought if I really needed it. And most of the time, I came to the conclusion that with some simple changes, I could eliminate it and make a cleaner design.
In this case, do you truly need to have a generic type with dynamic? My first and quick guess would be, you can probably use the non-generic IEnumerable.
Or if you want to save some casting, and you have different elements in there, you can find common ground to all element. I see that right now, all your property are string. Or if you want to return combination of elements, you can use some Tuple<>
If you truly end up returning a complete unknown types of lot of different objects, you could use IEnumerable<object>, but then I would question the reason of existence of that interface implementation. I don't remember ever creating an interface that would return object with absolutely any kind of common ground between the different implementation, or even within a single implementation. It could controls, numbers, components, entities... But they tend to share something. If it's properties, you could even pack in some PropertyInfo!
TL:DR; Unless you can present a very clear case where this design pattern would serve a very specific purpose that is unavoidable by any other means, I would recommend not using it. My IEnumerable of 2 cents.

Implementing phantom types in C#

I'm looking to use "phantom types" to implement type-safe identifiers. There's a question here about doing this in F#.
I'd like to do this in C#. How?
I've got a solution (which has problems), so I'll post it as a possible answer to see if anyone can improve it.
Why not make it a sealed class with its constructor private?
public sealed class Id<TDiscriminator>
{
private Id() { }
//some static methods
}
I've come up with the following:
struct Id<TDiscriminator>
{
private readonly Guid _id;
private Id(Guid id)
{
_id = id;
}
public Guid Value
{
get { return _id; }
}
public static Id<TDiscriminator> NewId()
{
return From(Guid.NewGuid());
}
public static Id<TDiscriminator> From(Guid id)
{
return new Id<TDiscriminator>(id);
}
public static readonly Id<TDiscriminator> Empty = From(Guid.Empty);
// Equality operators ellided...
}
...which I can use as follows:
class Order { /* empty */ }
class Customer { /* empty */ }
void Foo()
{
var orderId = Id<Order>.NewId();
var customerId = Id<Customer>.NewId();
// This doesn't compile. GOOD.
bool same = (orderId == customerId);
}
I don't particularly want concrete classes for the discriminator, because I don't want anyone instantiating them.
I could get around that by using an interface or an abstract class. Unfortunately, these can still be derived from and instantiated.
C# won't let you use a static class as a type argument. I can't say that I'm totally happy with the answers to that question, because the answers basically say "just because".
How about?
public sealed class Order
{
private Order() {}
}
public static sealed class Id<T>
{
// ...
}
I think that's exactly what you say. No one (except some special cases) can construct it and no one can inherit from it.
Well, as far as I could understand, you would like to provide a mechanism for distinguishing different types by a custom identifier object. I think you are almost near a working solution. In .NET when having a generic class, each substitution of the generic argument (or each unique combination of the generic arguments, if more than one) creates a unique type in the runtime. In your code Id<Order> and Id<Customer> are two distinct types. The NewId() method returns an instance of Id<Order> for the orderId and Id<Customer> for the customerId variables. The two types do not implement the == operator and therefore cannot be compared. Moreover, such comparison would be difficult to implement, since you cannot determine all possible uses of the Id<TDsicriminator> - you cannot guess what type will the TDsicriminator be substituted with.
1
A fast and simple solution will be to do this:
class Order { /* skipped */ }
class Customer { /* skipped */ }
void Foo()
{
var orderId = Id<Order>.NewId();
var customerId = Id<Customer>.NewId();
bool sameIds = (orderId.Value == customerId.Value); // true
bool sameObjects = orderId.Equals(customerId); // false
}
Since the Value properties are both of the Guid type, comparison is possible.
2
If you need however, to implement the == operator, or some sort of equality comparisons for instances of Id<TDisciminator>, the approach will be different. What comes up to my mind is the following:
public abstract class IdBase
{
public abstract Guid Value { get; protected set; }
public static bool operator == (IdBase left, IdBase right)
{
return left.Value == right.Value;
}
}
public sealed class Id<TDiscriminator> : IdBase
{
// your implementation here, just remember the override keyword for the Value property
}
Many people would not recommend the second approach though, since different implementations of IdBase may happen to have the same Value property (if you used the constructor that passes an existing ID). For instance:
var guid = Guid.NewGuid();
var customerID = Id<Customer>.From(guid);
var orderID = Id<Order>.From(guid);
Here (customerID == orderID) will then return true which is probably not what you want.
Shortly, in such a case, two different types will count as equal, which is a big logical mistake, so I'd stick to the first approach.
If you need Id<Customer>.Value to always be different than Id<Order>.Value, because of the different generic arguments (Customer is different than Order), then the following approach will work:
public sealed class Id<in TDiscriminator>
{
private static readonly Guid _idStatic = Guid.NewGuid();
private Id()
{
}
public Guid Value
{
get { return _idStatic; }
}
}
Notice the in keyword used here. This is applicable for .NET 4.0 where generics can be covariant and ensures that your class uses contravariant generics. (see http://msdn.microsoft.com/en-us/library/dd469487.aspx). In the above code, the _idStatic field will have a unique value for every different type supplied as a generic argument.
I hope this info is helpful.

Override/Handle My Own Type Conversions In .Net [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Is there a way to define an implicit conversion operator in VB.NET?
I can't remember ever seeing or hearing of anyone do this; but now I'm in a situation where I think it would be incredibly useful to define my own custom 'type conversion' for my class.
As an example - let's say I have my own class, 'AwesomeDataManager'. It does not inherit from DataTable, but it holds data in a similar fashion to a DataTable. I would to be able to say, 'myDataTable = CType(MyAwesomeDataManager, DataTable)' and have it execute some code inside my class that would return a populated DataTable.
Granted, I could do something like 'MyAwesomeDataManager.GetDataTable' but for the sake of integrating with an existing code base, I'd like to avoid it.
You could use an implicit or explicit cast, like this: (Note that LetMeChange is implicitly cast to SomethingMoreComfortable)
class Program
{
static void Main(string[] args)
{
LetMeChange original = new LetMeChange { Name = "Bob" };
SomethingMoreComfortable casted = original;
Console.WriteLine(casted.Name);
}
}
public class LetMeChange
{
public static implicit operator SomethingMoreComfortable(LetMeChange original)
{
return new SomethingMoreComfortable() { Name = original.Name };
}
public string Name
{
get;
set;
}
}
public class SomethingMoreComfortable
{
public string Name
{
get;
set;
}
}
There are two keywords in C# that help with type conversions: implicit and explicit.
In this case, you would want implicit for code eye-candy. Be careful with this however, as it can cause moments of confusion as people realise what you are doing. I tend to not spot the use of implicit conversions just by reading the code quickly (explicit are hard to miss as they need casts).

Categories