简体   繁体   中英

Is there a way to make use of an abstract class' import in the concrete class?

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.

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.

除非您在单个文件中定义所有类,否则不要。

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

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.

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 (ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM