0

I have this abstract class:

using TypeLib=some.type.library;

namespace someSpace
{
 abstract class Creator
 {
  abstract public TypeLib.SomeObject createObject();
 }

}

Here's a concrete class:

using TypeLib=some.type.library;

namespace someSpace
{
 class SpecialCreator:Creator
 {
  override public TypeLib.SomeObject createObject()
  {
    doSomethingSpecial();  
    return new TypeLib.SomeObject();
  }
 }

}

Because I will want to implement Creator several different ways, all of which require importing some.type.library because they need to return a TypeLib.someObject, is there a way that I can just have the using statement at some high level and have it be inherited by all the implementations? When I didn't include the using statement in SpecialCreator(), it didn't have access to TypeLib.

EDIT: I think this is different than the duplicate directives question. I'm not trying to consolidate different using statements into one master using that I will then add to many classes; instead, I want to put one using statement in a parent class/header file/static class/etc so that it can be accessible to many classes without having to add the same line of code to each class. Let me know if I've misunderstood the duplicate directives question.

Community
  • 1
  • 1
sigil
  • 9,370
  • 40
  • 119
  • 199
  • No. You need to explicitly include a using in each .cs file. – garryp Apr 29 '15 at 21:33
  • Why not just create a new type that derives from TypeLib.SomeObject and use that in the classes? Its implicitly convertable back to the base type... – Ron Beyer Apr 29 '15 at 21:34
  • possible duplicate of [Duplicated using directives in multiple files](http://stackoverflow.com/questions/24512894/duplicated-using-directives-in-multiple-files) – Joe Farrell Apr 29 '15 at 21:35
  • @JoeFarrell, I think it's different, please see edit. – sigil Apr 29 '15 at 22:53
  • @RonBeyer, do you mean creating a public static class that basically aliases `TypeLib`? If so, can you point me to an example of this? I'm not exactly sure how to do this, or even how to look it up. – sigil Apr 29 '15 at 22:56
  • @sigil no, not static, but yes, something like `public class MyTypeLib : TypeLib.SomeObject { }` – Ron Beyer Apr 29 '15 at 23:49
  • @RonBeyer, ok, so I'd have to make a separate class for each `TypeLib` class that I want to use, like `SomeObj:TypeLib.SomeObject{}` and `SomeOtherObj:TypeLib.SomeOtherObject{}`, and there's no way to just have something that encapsulates `TypeLib` itself? – sigil Apr 30 '15 at 00:43
  • @sigil if `TypeLib` is a class, then you can just inherit that class and the subclasses will show up. If `TypeLib` is a namespace, then there's no other way around it. – Ron Beyer Apr 30 '15 at 00:52
  • @RonBeyer, `TypeLib` is a namespace, so I guess I'll have to duplicate it or encapsulate its subclasses. BTW I just realized I asked a similar question a couple years ago [here](http://stackoverflow.com/questions/13635829/how-to-make-a-type-available-in-all-namespaces), so maybe I should close? – sigil Apr 30 '15 at 16:37

5 Answers5

1

It depends. If TypeLib is only used in base class functionality there is no reason to include 'using TypeLib;' in the files that contain the concrete implementations.

If the desired architecture is intended to encapsulate TypeLib in the abstract base class, the need to have the using statement is an indicator that encapsulation has been broken.

Martin Fowler may say the requirement to 'use' TypeLib in all the concrete implementations is the smell of tight coupling between the class tree under the base class and TypeLib. Using an adapter class may reduce the coupling by putting all TypeLib uses into the adapter.

Steve
  • 623
  • 4
  • 11
0

Not unless you define all classes within a single file.

tdi
  • 1
  • 2
0

It depends on what you are trying to do.

If you are just trying to avoid having to add this in each and every page of your derived class, your'd be better off using Visual Studio's Export Template (under the File menu). Pick the Item Template and your added template will show up in the Add > New Item List. I think this would be cleanest.

Of course, there is a sneaky way to do avoid the using itself altogether, but I don't think it's good design. Notice I changed the namespace.

namespace some.type.library;
{
 class SpecialCreator:Creator
 {
  override public SomeObject createObject()
  {
    doSomethingSpecial();  
    return new SomeObject();
  }
 }
}

You could also instead, derive a class in your someSpace namespace from TypeLib.SomeObject (no body for the class) and use this new class wherever you were using TypeLib.SomeObject

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
0

You could "alias" the type by creating a child class of it for internal use. For example:

namespace Remote.Namespace
{
    public class TypeLib
    {
        public class SomeObject
        {

        }
    }
}

namespace Internal.Namespace
{
    public class InternalTypeLibObject : Remote.Namespace.TypeLib.SomeObject
    {

    }
}

And now you can use InternalTypeLibObject without having to alias the namespace and cast it to TypeLib.SomeObject.

Now for the drawbacks:

If you want to use the constructors in the parent class, you will need to provide mirror constructors and call the base constructor with constructor chaining. Also, if the parent class is sealed, this won't work.

Honestly though you shouldn't be concerned too much about a little typing. Hiding classes like this can add to confusion and should probably be avoided unless you have a reason to extend the type.

Ron Beyer
  • 11,003
  • 1
  • 19
  • 37
0

using is just a syntactic sugar to save you from typing fully qualified type names each time you type them. It's a hint for compiler for places where to look for type names.

So unless you actually use types from TypeLib you don't have to add using statement in each implementation even if some base class of that concrete implementation uses it in some way (i.e. derives from it). And even if your concrete implementation use types from TypeLib you can avoid using statement by specifying fully qualified type names from that library each time.

n0rd
  • 11,850
  • 5
  • 35
  • 56