I would assume the general consensus is that you place them anywhere
that makes sense for the use case, but in general I feel there is a
best way to structure everything in a solution to minimise problems,
promote positive modularity, and ease maintenance.
Well yes, in the general case, you can just put everything wherever you please it. However, the problems start when you're working in a team. In a team, other people have to understand the structure of the program to be able to create code effectively. That implies consistency, which is the end goal.
So, it's not just a matter of intuition; in all the companies that I've worked in, I've started by writing a coding standard and aggressively enforcing it everywhere. In this coding standard, I usually put a ton of good/bad practices involving threading, static use, placement of variables / classes, etc.
Iirc this link http://se.inf.ethz.ch/old/teaching/ss2007/251-0290-00/project/CSharpCodingStandards.pdf and https://msdn.microsoft.com/en-us/library/ff926074.aspx will give you a head start, although the former is a bit outdated and both don't really answer your question. It might however help with what you're trying to achieve in the long run.
[...] I currently have delegates in
their own file, in a 'delegate' namespace. Is there an oversight I am
making by doing so, or am I overcomplicating the use case for
delegates - or is this inline with current usage expectations?
A common library with interfaces makes sense. An interface is essentially a contract between 'client' and 'server', which is an important asset for decoupling a piece of software.
You have to realize at this point that the 'interface' part is a functional decomposition, not a technical one. In other words: the fact that you need an 'interface' library is a matter of contract, not of technical constructs. As such, I don't see why you would ever put classes in a 'classes' folder and why you would put delegates in a 'delegates' folder. In short, a 'delegates' folder doesn't make any sense to me. Put the stuff where it belongs.
At this point, you have a decision to make. (1) You can put a delegate in a single file, (2) you can put a delegate in the class file where it's used (I usually use delegates for a single purpose), (3) you can do both depending on single / multi purpose and (4) you can put single-purpose delegates nested within the class. This basically means you're treating a delegate as a function pointer description, and don't see it as a real 'class'.
Looking at functional decomposition, you can argue that a function pointer belongs to a class, just like methods.
So to concluse. Personally I usually go for option (2) or (3) because it's brief, clear and concise, and doesn't have an impact on the amount of 'typing work' like (4) . Picking (1) will probably bloat your application with small files that have little or no purpose, which will confuse other developers.
interfaces
, viz in an independent assembly, such that both the publisher / implementation and subscriber / callback code are both coupled on the delegates assembly (and any types they use), and not directly to eachother. I have to admit nowadays it is more common to see nakedFunc
orAction
s with no explicit delegate type (Similar thinking to Generic IEnumerables and ILists<> etc). – Gilbertegilbertian