Reputation: 34297
Edit: My question isn't about a using block and how it works. My question is about the difference in the two ways to do it, shown below.
I'm reading the CQRS Journey Guide, and I don't understand this line of code:
using (repo as IDisposable)
What does that mean? Why use it as IDisposable? In a typical using block, one doesn't need to use it as IDisposable:
using (var repo = this.respositoryFactory()) { // ... }
Any idea why the authors wrote it the first way instead of the second way?
This is the method in which that code appears:
private Conference.Web.Public.Models.Conference GetConference(string conferenceCode)
{
var repo = this.repositoryFactory();
using (repo as IDisposable)
{
var conference = repo.Query<Conference>()
.First(c => c.Code == conferenceCode);
var conferenceModel =
new Conference.Web.Public.Models.Conference
{
Code = conference.Code,
Name = conference.Name,
Description = conference.Description
};
return conferenceModel;
}
}
Upvotes: 3
Views: 1032
Reputation: 564433
Any idea why the authors wrote it the first way instead of the second way?
This is often due to a misunderstanding of the language feature. The way you wrote it is the idomatic way to write it in C#:
using (var repo = this.respositoryFactory())
{
The only real advantage to the author's approach would be if repositoryFactory
could, potentially, return a type which doesn't implement IDisposable
. By writing the code via using (repo as IDisposable)
, the same code could handle non-disposable types.
Most of the time, this isn't an issue. However, it would be possible that the factory could optionally return an IDisposable
type. As an example, suppose this method was done within a generic class, and repositoryFactory
returned an IRepository<T>
, it would be possible that type may or may not implement IDiposable
, in which case this approach would handle both cases without imposing an IDisposable
constraint on the generic type.
Upvotes: 10
Reputation: 81169
Saying using(X as IDisposable)
instructs the compiler that X identifies a particular instance of a type which implements IDisposable
, then the using
block should guard that instance, and otherwise it should guard nothing. Such a usage would be appropriate if the return type of the method this.repositoryFactory()
did not implement IDisposable
, but the method would sometimes return instances of types which do implement IDisposable
and expect it to be called.
Note that any type which will be used as the return type of a factory that may produce IDisposable
objects needing cleanup should implement IDisposable
, even if only 99.9% of the objects generated would have Dispose
methods that do nothing and don't actually have to be called. The non-generic IEnumerator
fits that description to a "T", and thus should have implement IDisposable
, but since it doesn't the best usage pattern is probably:
IEnumerator enumerator = myEnumerable.GetEnumerator();
using (enumerator as IDisposable)
{
...
}
Very similar to what is observed in the code using repositoryFactory()
above.
Upvotes: 3
Reputation: 3109
if somewhere in the using block the code fails, or reach a point of exception. Its guaranteed that repo is beeing disposed.
Difference between the two lines is that there is no difference. cast to IDisposable is not nessecary, it is purely theorethical. possible differences
Upvotes: 0