Ways to synchronize interface and implementation comments in C#
You can do this quite easily using the Microsoft Sandcastle (or NDoc) inheritdoc
tag. It's not officially supported by the specification, but custom tags are perfectly acceptable, and indeed Microsoft chose to copy this (and one or two other tags) from NDoc when they created Sandcastle.
/// <inheritdoc/>
/// <remarks>
/// You can still specify all the normal XML tags here, and they will
/// overwrite inherited ones accordingly.
/// </remarks>
public void MethodImplementingInterfaceMethod(string foo, int bar)
{
//
}
Here is the help page from the Sandcastle Help File Builder GUI, which describes its usage in full.
(Of course, this isn't specifically "synchronisation", as your question mentions, but it would seem to be exactly what you're looking for nonetheless.)
As a note, this sounds like a perfectly fair idea to me, though I've observed that some people think you should always respecify comments in derived and implemented classes. (I've actually done it myself in documenting one of my libraries and I haven't see any problems whatsoever.) There's almost always no reason for the comments to differ at all, so why not just inherit and do it the easy way?
Edit: Regarding your update, Sandcastle can also take care of that for you. Sandcastle can output a modified version of the actual XML file it uses for input, which means you can distribute this modified version along with your library DLL instead of the one built directly by Visual Studio, which means you have the comments in intellisense as well as the documentation file (CHM, whatever).
Comment the interface, implementation or both?
As a general rule, I use the same DRY (Don't Repeat Yourself) principle as with code:
- on interface, document the interface
- on implementation, document the implementation specifics
Java specific: when documenting the implementation, use {@inheritDoc} tag to "include" javadocs from the interface.
For more information:
- Official javadoc documentation
- Some unofficial advice.
Inheriting comments from an interface in an implementing class?
GhostDoc does exactly that. For methods which aren't inherited, it tries to create a description out of the name.
FlingThing()
becomes "Flings the Thing"
Where to use synchronized methods in C# : Interfaces or implementations?
It does no good on the interface, because MethodImplAttribute
is itself marked AttributeUsageAttribute.Inherited = false
But this is an anti-pattern anyway, the documentation says
Locking on the instance or on the type, as with the
Synchronized
flag, is not recommended for public types, because code other than your own can take locks on public types and instances. This might cause deadlocks or other synchronization problems.
Instead implementations should lock (if not internally threadsafe) on an instance of object
which is private
to the class.
The problems of declarative synchronization are well-known -- it leads to lock order inversions -- and so the recommendation against using it is universal.
Can implementation classes inherit XML comments from their implemented interfaces?
This feature does not exist currently in Visual Studio.
You can get third party tools, such as GhostDoc that will help with creating XML documentation. GhostDoc also has the option to generate documentation that was "inherited" like you are attempting to do.
Link: GhostDoc
Infrastructure - both sync & async interface & implementation?
When implementing a library/infrastructure, and the user of this API would want to use the code both synchronously & asynchronously
Ideally, each API in your library should either be naturally synchronous or naturally asynchronous. I recommend exposing only the most natural API. I.e., if your library needs to do I/O, it could choose to only expose an asynchronous API.
Is there an elegant way to avoid code (or more accurately "flow") duplication for sync & async implementations, which would obviously bubble down to the whole call hierarchy?
I've not found an ideal solution for this. The closest I've come is the boolean argument hack, where you have asynchronous and synchronous APIs both forward to an internal method that takes a bool sync
argument. This internal method has an asynchronous signature (returning a Task
/Task<T>
), but if sync
is true
, it always returns a completed task.
This ends up looking like this:
interface IMyInterface
{
void Foo();
Task FooAsync();
}
class MyImplementation1 : IMyInterface
{
public void Foo() => Foo(sync: true).GetAwaiter().GetResult();
public Task FooAsync() => Foo(sync: false);
private async Task Foo(bool sync)
{
// Pass `sync` along to all methods that can be sync or async.
await OtherMethod1(sync);
await OtherMethod2(sync);
await OtherMethod3(sync);
await OtherMethod4(sync);
}
private async Task OtherMethod1(bool sync)
{
// When you have to choose sync/async APIs of other classes, then choose based on `sync`.
if (sync)
Thread.Sleep(1000); // synchronous placeholder
else
await Task.Delay(1000); // asynchronous placeholder
}
}
Synchronous implementation of interface that returns Task
If you really do want to do the work synchronously, you know that your async
method will always run synchronously, and that's desirable in the situation, then by all means, ignore the warning. If you understand what the warning is telling you and feel that the action it is describing is correct, then it's not a problem. There's a reason it's a warning and not an error after all.
Of course, the other option is to just not make the method async
and to simply use Task.FromResult
to return an already completed task instead. It would change the error handling semantics (unless you also catch all exceptions and wrap them into a task that you return) so at least be mindful of that. If you really want exceptions to be propagated through the resulting Task
, it may be worth leaving the method async
and just suppressing the warning.
Related Topics
Blocking Access to Private Member Variables? Force Use of Public Properties
How to Interact with Windows Media Player in C#
How to Highlight Wrapped Text in a Control Using the Graphics
Httpcontext.Current Is Null When Unit Test
How to Compile and Run C# Program Without Using Visual Studio
.Net (3.5) Formats Times Using Dots Instead of Colons as Timeseparator for It-It Culture
Auto-Resize Multiple Forms Rendered on Panel
What Does Linq Return When the Results Are Empty
Run a Background Task from a Controller Action in ASP.NET Core
Wcf - Design Parameter Decision
How to Click on the Radio Button Through the Element Id Attribute Using Selenium and C#
How to Create "Embedded" SQL 2008 Database File If It Doesn't Exist
C# Code for Association, Aggregation, Composition
Generate Class from Database Table
Using Iconfiguration in C# Class Library
Getting Time Span Between Two Times in C#