Covariance and Contravariance related understanding the point and architectureFluent LinkedIn REST API client interface designWrapper class for the Rotten Tomatoes APIIs this common way to build this class and method?Implementing SOLID Principles with C# Asp.netC++ application calling C# Dll marshalling stringsObject to object mapping verification - is this extension method useful?Converting from binary to unaryCode First approach, feeding the tableRectangle ClassGenerate URLs, Download, extract and add files
Emailing HOD to enhance faculty application
Why is consensus so controversial in Britain?
I Accidentally Deleted a Stock Terminal Theme
How to model explosives?
I would say: "You are another teacher", but she is a woman and I am a man
Does a druid starting with a bow start with no arrows?
Is it canonical bit space?
How could indestructible materials be used in power generation?
What is the intuition behind short exact sequences of groups; in particular, what is the intuition behind group extensions?
What mechanic is there to disable a threat instead of killing it?
Can a virus destroy the BIOS of a modern computer?
How can I prevent hyper evolved versions of regular creatures from wiping out their cousins?
Is "remove commented out code" correct English?
What is a clear way to write a bar that has an extra beat?
What do you call someone who asks many questions?
What killed these X2 caps?
Why is Collection not simply treated as Collection<?>
Were any external disk drives stacked vertically?
Took a trip to a parallel universe, need help deciphering
Intersection of two sorted vectors in C++
Blender 2.8 I can't see vertices, edges or faces in edit mode
What is going on with Captain Marvel's blood colour?
What to put in ESTA if staying in US for a few days before going on to Canada
Stopping power of mountain vs road bike
Covariance and Contravariance related understanding the point and architecture
Fluent LinkedIn REST API client interface designWrapper class for the Rotten Tomatoes APIIs this common way to build this class and method?Implementing SOLID Principles with C# Asp.netC++ application calling C# Dll marshalling stringsObject to object mapping verification - is this extension method useful?Converting from binary to unaryCode First approach, feeding the tableRectangle ClassGenerate URLs, Download, extract and add files
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
First of all apologize for long post nevertheless i wanted to highlight problem exactly and to be most readable and understandably. I am developing architecture of my program which will be responsible for files/databases data gather and face some architecture issues so far. All information step by step down below.
Let's consider following code below:
public interface IWatchService<TEntity> where TEntity : IEntity
IList<TEntity> MatchingEntries get; set;
public interface IWatchServiceDatabase<TEntity> : IWatchService<TEntity> where TEntity : IDatabaseEntity
public interface IWatchServiceFiles<TEntity> : IWatchService<TEntity> where TEntity : IFileEntity
class Database : IWatchServiceDatabase<DatabaseQuery>
public IList<DatabaseQuery> MatchingEntries get; set;
class Files : IWatchServiceFiles<CsvFile>
public IList<CsvFile> MatchingEntries get; set;
class Consumer
public IWatchService<IEntity> WatchService get; set;
public Consumer(IWatchService<IEntity> watchService)
WatchService = watchService;
var newList = WatchService.MatchingEntries;
public void AddNewEntries(IEntity entity) => WatchService.MatchingEntries.Add(entity);
class Program
static void Main(string[] args)
IWatchServiceDatabase<DatabaseQuery> db = new Database();
IWatchServiceFiles<CsvFile> filesCsv = new Files();
var dbConsumer = new Consumer(db); //cannot convert from 'IWatchServiceDatabase<DatabaseQuery>' to 'IWatchService<IEntity>'
var filesCsvConsumer = new Consumer(filesCsv); //cannot convert from 'IWatchServiceFiles<CsvFile>' to 'IWatchService<IEntity>'
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
public interface IEntity
public interface IFileEntity : IEntity
int Id get; set;
string Name get; set;
public interface IDatabaseEntity : IEntity
public class CsvFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class XmlFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class DatabaseQuery : IDatabaseEntity
We have two errors there:
var dbConsumer = new Consumer(db);
var filesCsvConsumer = new Consumer(filesCsv);
Errors:
cannot convert from 'IWatchServiceDatabase' to 'IWatchService'
cannot convert from 'IWatchServiceFiles' to 'IWatchService'
This seems to be understandable because otherwise "we would be able" to add CsvFile
or XmlFile
to dbConsumer
where generic IDatabaseEntity
is expected and CsvFile
and XmlFile
are in fact IFileEntity
and from the other hand DatabaseQuery
to filesConsumer
which expects IFileEntity
and DatabaseQuery
is IDatabaseEntity
//Database related
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
//Files related
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
From my understanding this is the clue why compiler raise those errors and which is fine. Therefore I've decided to overcome it in this way:
public interface IWatchService<out TEntity> where TEntity : IEntity
IEnumerable<TEntity> MatchingEntries get;
As can be seen i marked generic parameter out and changed IList to IEnumerable
because IEnumerable
can be only foreached
. Without possibility to modify the list.
Now having this there is no possibility to modify MatchingEntries
e.g Add()
on therefore we are now not able to add e.g CsvFile (IFileEntity)
where IDatabaseEntity
is expected and vice versa DatabaseQuery (IDatabaseEntity)
where IFileEntity
is expected. Fine and understandably.
At the end i have two main questions:
What is the benefit to have this: IEnumerable MatchingEntries get;
since it's get;
it cannot be initialized or populated with values therefore i would always get empty list when calling that property. Or i am in wrong? Can somebody explain showing based on my code what can be done with it?
Let's imagine i want to have possibility to Add items
to this MatchingEntries
list and in Consumer
class i want still to be able to pass in ctor
either Database
or Files
related classes based on interfaces. How this can be accomplished? Please also show an example based on current code.
Many thanks for your support and hope someone benefit from it as i saw a lot of confusions related to that topic.
c#
New contributor
$endgroup$
add a comment |
$begingroup$
First of all apologize for long post nevertheless i wanted to highlight problem exactly and to be most readable and understandably. I am developing architecture of my program which will be responsible for files/databases data gather and face some architecture issues so far. All information step by step down below.
Let's consider following code below:
public interface IWatchService<TEntity> where TEntity : IEntity
IList<TEntity> MatchingEntries get; set;
public interface IWatchServiceDatabase<TEntity> : IWatchService<TEntity> where TEntity : IDatabaseEntity
public interface IWatchServiceFiles<TEntity> : IWatchService<TEntity> where TEntity : IFileEntity
class Database : IWatchServiceDatabase<DatabaseQuery>
public IList<DatabaseQuery> MatchingEntries get; set;
class Files : IWatchServiceFiles<CsvFile>
public IList<CsvFile> MatchingEntries get; set;
class Consumer
public IWatchService<IEntity> WatchService get; set;
public Consumer(IWatchService<IEntity> watchService)
WatchService = watchService;
var newList = WatchService.MatchingEntries;
public void AddNewEntries(IEntity entity) => WatchService.MatchingEntries.Add(entity);
class Program
static void Main(string[] args)
IWatchServiceDatabase<DatabaseQuery> db = new Database();
IWatchServiceFiles<CsvFile> filesCsv = new Files();
var dbConsumer = new Consumer(db); //cannot convert from 'IWatchServiceDatabase<DatabaseQuery>' to 'IWatchService<IEntity>'
var filesCsvConsumer = new Consumer(filesCsv); //cannot convert from 'IWatchServiceFiles<CsvFile>' to 'IWatchService<IEntity>'
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
public interface IEntity
public interface IFileEntity : IEntity
int Id get; set;
string Name get; set;
public interface IDatabaseEntity : IEntity
public class CsvFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class XmlFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class DatabaseQuery : IDatabaseEntity
We have two errors there:
var dbConsumer = new Consumer(db);
var filesCsvConsumer = new Consumer(filesCsv);
Errors:
cannot convert from 'IWatchServiceDatabase' to 'IWatchService'
cannot convert from 'IWatchServiceFiles' to 'IWatchService'
This seems to be understandable because otherwise "we would be able" to add CsvFile
or XmlFile
to dbConsumer
where generic IDatabaseEntity
is expected and CsvFile
and XmlFile
are in fact IFileEntity
and from the other hand DatabaseQuery
to filesConsumer
which expects IFileEntity
and DatabaseQuery
is IDatabaseEntity
//Database related
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
//Files related
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
From my understanding this is the clue why compiler raise those errors and which is fine. Therefore I've decided to overcome it in this way:
public interface IWatchService<out TEntity> where TEntity : IEntity
IEnumerable<TEntity> MatchingEntries get;
As can be seen i marked generic parameter out and changed IList to IEnumerable
because IEnumerable
can be only foreached
. Without possibility to modify the list.
Now having this there is no possibility to modify MatchingEntries
e.g Add()
on therefore we are now not able to add e.g CsvFile (IFileEntity)
where IDatabaseEntity
is expected and vice versa DatabaseQuery (IDatabaseEntity)
where IFileEntity
is expected. Fine and understandably.
At the end i have two main questions:
What is the benefit to have this: IEnumerable MatchingEntries get;
since it's get;
it cannot be initialized or populated with values therefore i would always get empty list when calling that property. Or i am in wrong? Can somebody explain showing based on my code what can be done with it?
Let's imagine i want to have possibility to Add items
to this MatchingEntries
list and in Consumer
class i want still to be able to pass in ctor
either Database
or Files
related classes based on interfaces. How this can be accomplished? Please also show an example based on current code.
Many thanks for your support and hope someone benefit from it as i saw a lot of confusions related to that topic.
c#
New contributor
$endgroup$
add a comment |
$begingroup$
First of all apologize for long post nevertheless i wanted to highlight problem exactly and to be most readable and understandably. I am developing architecture of my program which will be responsible for files/databases data gather and face some architecture issues so far. All information step by step down below.
Let's consider following code below:
public interface IWatchService<TEntity> where TEntity : IEntity
IList<TEntity> MatchingEntries get; set;
public interface IWatchServiceDatabase<TEntity> : IWatchService<TEntity> where TEntity : IDatabaseEntity
public interface IWatchServiceFiles<TEntity> : IWatchService<TEntity> where TEntity : IFileEntity
class Database : IWatchServiceDatabase<DatabaseQuery>
public IList<DatabaseQuery> MatchingEntries get; set;
class Files : IWatchServiceFiles<CsvFile>
public IList<CsvFile> MatchingEntries get; set;
class Consumer
public IWatchService<IEntity> WatchService get; set;
public Consumer(IWatchService<IEntity> watchService)
WatchService = watchService;
var newList = WatchService.MatchingEntries;
public void AddNewEntries(IEntity entity) => WatchService.MatchingEntries.Add(entity);
class Program
static void Main(string[] args)
IWatchServiceDatabase<DatabaseQuery> db = new Database();
IWatchServiceFiles<CsvFile> filesCsv = new Files();
var dbConsumer = new Consumer(db); //cannot convert from 'IWatchServiceDatabase<DatabaseQuery>' to 'IWatchService<IEntity>'
var filesCsvConsumer = new Consumer(filesCsv); //cannot convert from 'IWatchServiceFiles<CsvFile>' to 'IWatchService<IEntity>'
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
public interface IEntity
public interface IFileEntity : IEntity
int Id get; set;
string Name get; set;
public interface IDatabaseEntity : IEntity
public class CsvFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class XmlFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class DatabaseQuery : IDatabaseEntity
We have two errors there:
var dbConsumer = new Consumer(db);
var filesCsvConsumer = new Consumer(filesCsv);
Errors:
cannot convert from 'IWatchServiceDatabase' to 'IWatchService'
cannot convert from 'IWatchServiceFiles' to 'IWatchService'
This seems to be understandable because otherwise "we would be able" to add CsvFile
or XmlFile
to dbConsumer
where generic IDatabaseEntity
is expected and CsvFile
and XmlFile
are in fact IFileEntity
and from the other hand DatabaseQuery
to filesConsumer
which expects IFileEntity
and DatabaseQuery
is IDatabaseEntity
//Database related
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
//Files related
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
From my understanding this is the clue why compiler raise those errors and which is fine. Therefore I've decided to overcome it in this way:
public interface IWatchService<out TEntity> where TEntity : IEntity
IEnumerable<TEntity> MatchingEntries get;
As can be seen i marked generic parameter out and changed IList to IEnumerable
because IEnumerable
can be only foreached
. Without possibility to modify the list.
Now having this there is no possibility to modify MatchingEntries
e.g Add()
on therefore we are now not able to add e.g CsvFile (IFileEntity)
where IDatabaseEntity
is expected and vice versa DatabaseQuery (IDatabaseEntity)
where IFileEntity
is expected. Fine and understandably.
At the end i have two main questions:
What is the benefit to have this: IEnumerable MatchingEntries get;
since it's get;
it cannot be initialized or populated with values therefore i would always get empty list when calling that property. Or i am in wrong? Can somebody explain showing based on my code what can be done with it?
Let's imagine i want to have possibility to Add items
to this MatchingEntries
list and in Consumer
class i want still to be able to pass in ctor
either Database
or Files
related classes based on interfaces. How this can be accomplished? Please also show an example based on current code.
Many thanks for your support and hope someone benefit from it as i saw a lot of confusions related to that topic.
c#
New contributor
$endgroup$
First of all apologize for long post nevertheless i wanted to highlight problem exactly and to be most readable and understandably. I am developing architecture of my program which will be responsible for files/databases data gather and face some architecture issues so far. All information step by step down below.
Let's consider following code below:
public interface IWatchService<TEntity> where TEntity : IEntity
IList<TEntity> MatchingEntries get; set;
public interface IWatchServiceDatabase<TEntity> : IWatchService<TEntity> where TEntity : IDatabaseEntity
public interface IWatchServiceFiles<TEntity> : IWatchService<TEntity> where TEntity : IFileEntity
class Database : IWatchServiceDatabase<DatabaseQuery>
public IList<DatabaseQuery> MatchingEntries get; set;
class Files : IWatchServiceFiles<CsvFile>
public IList<CsvFile> MatchingEntries get; set;
class Consumer
public IWatchService<IEntity> WatchService get; set;
public Consumer(IWatchService<IEntity> watchService)
WatchService = watchService;
var newList = WatchService.MatchingEntries;
public void AddNewEntries(IEntity entity) => WatchService.MatchingEntries.Add(entity);
class Program
static void Main(string[] args)
IWatchServiceDatabase<DatabaseQuery> db = new Database();
IWatchServiceFiles<CsvFile> filesCsv = new Files();
var dbConsumer = new Consumer(db); //cannot convert from 'IWatchServiceDatabase<DatabaseQuery>' to 'IWatchService<IEntity>'
var filesCsvConsumer = new Consumer(filesCsv); //cannot convert from 'IWatchServiceFiles<CsvFile>' to 'IWatchService<IEntity>'
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
public interface IEntity
public interface IFileEntity : IEntity
int Id get; set;
string Name get; set;
public interface IDatabaseEntity : IEntity
public class CsvFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class XmlFile : IFileEntity
public int Id get; set;
public string Name get; set;
public class DatabaseQuery : IDatabaseEntity
We have two errors there:
var dbConsumer = new Consumer(db);
var filesCsvConsumer = new Consumer(filesCsv);
Errors:
cannot convert from 'IWatchServiceDatabase' to 'IWatchService'
cannot convert from 'IWatchServiceFiles' to 'IWatchService'
This seems to be understandable because otherwise "we would be able" to add CsvFile
or XmlFile
to dbConsumer
where generic IDatabaseEntity
is expected and CsvFile
and XmlFile
are in fact IFileEntity
and from the other hand DatabaseQuery
to filesConsumer
which expects IFileEntity
and DatabaseQuery
is IDatabaseEntity
//Database related
dbConsumer.AddNewEntries(new DatabaseQuery());
dbConsumer.AddNewEntries(new CsvFile()); //illegal cause it's not FileConsumer !!!
//Files related
filesCsvConsumer.AddNewEntries(new CsvFile());
filesCsvConsumer.AddNewEntries(new DatabaseQuery()); //illegal cause it's not DbConsumer !!!
From my understanding this is the clue why compiler raise those errors and which is fine. Therefore I've decided to overcome it in this way:
public interface IWatchService<out TEntity> where TEntity : IEntity
IEnumerable<TEntity> MatchingEntries get;
As can be seen i marked generic parameter out and changed IList to IEnumerable
because IEnumerable
can be only foreached
. Without possibility to modify the list.
Now having this there is no possibility to modify MatchingEntries
e.g Add()
on therefore we are now not able to add e.g CsvFile (IFileEntity)
where IDatabaseEntity
is expected and vice versa DatabaseQuery (IDatabaseEntity)
where IFileEntity
is expected. Fine and understandably.
At the end i have two main questions:
What is the benefit to have this: IEnumerable MatchingEntries get;
since it's get;
it cannot be initialized or populated with values therefore i would always get empty list when calling that property. Or i am in wrong? Can somebody explain showing based on my code what can be done with it?
Let's imagine i want to have possibility to Add items
to this MatchingEntries
list and in Consumer
class i want still to be able to pass in ctor
either Database
or Files
related classes based on interfaces. How this can be accomplished? Please also show an example based on current code.
Many thanks for your support and hope someone benefit from it as i saw a lot of confusions related to that topic.
c#
c#
New contributor
New contributor
New contributor
asked 7 mins ago
HenryHenry
1
1
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Henry is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216905%2fcovariance-and-contravariance-related-understanding-the-point-and-architecture%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Henry is a new contributor. Be nice, and check out our Code of Conduct.
Henry is a new contributor. Be nice, and check out our Code of Conduct.
Henry is a new contributor. Be nice, and check out our Code of Conduct.
Henry is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216905%2fcovariance-and-contravariance-related-understanding-the-point-and-architecture%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown