简体   繁体   中英

is there an explicit interface declaration for abstract methods?

i have a (quite easy) problem and it seems I can't find out how to do it. I would appreciate some help.

I have two classes which are something like this:

public class FileParameters { ... }

public abstract class File {
    ...
    public abstract FileParameters Params { get; }
}

From both classes I have a derived special version:

public class SpecialFileParameters { ... }

public abstract class SpecialFile {
    ...
    private SpecialFileParameters params;
    public override FileParameters Params { get { return params; } }
}

When I want to use the SpecialFileParameters I have to cast them first, eg:

((SpecialFileParameters)SpecialFileObject.Parameters).DoSomething();

which is quite obnoxious. What I would like to have is basically the same syntax as with interfaces

public abstract class SpecialFile {
    ...
    private SpecialFileParameters params;
    private override FileParameters File.Params { get { return params; } }
    public new SpecialFileParameters Params { get { return params; } }
}

But like this i get an compiler error: 'File' in explicit interface declaration is not an interface. Is there some other way to do this?

Some further information:

  • I cannot change the base classes, only my special classes
  • I actually need 2 special derived classes, one is written in C#, the other in C++/CLI. If the "trick" to makes it work is different between C# and C++ CLI please let me know.

Thanks for your help (and patience I guess ^^),

It is somewhat different in C++/CLI, example of explicit overriding:

public ref struct BaseClass abstract
{
    virtual int Func(int) abstract;
};

public ref struct DerivedClass : BaseClass
{
    virtual int BaseFunc(int x) = BaseClass::Func { return x + 2; }
    virtual int Func(int y) new { return y / 2; }
};

int main(array<System::String ^> ^args)
{
    DerivedClass^ d = gcnew DerivedClass();
    BaseClass^ b = d;
    System::Console::WriteLine("4 ->  Base   -> " + b->Func(4));
    System::Console::WriteLine("4 -> Derived -> " + d->Func(4));

    return 0;
}

Marc has shown what you need to do for C#: use an additional layer of inheritance.

No, there's no syntax in C# for marking an explicit abstract override method (as distinct from another method with the same signature), and since you can't have two matching signatures declared in the same level you can't do quite what you want.

Since you've ruled out changing the base class, the only suggestion I have is to add an artificial extra level:

public abstract class File {
    public abstract FileParameters Params { get; }
}
public abstract class FileIntermediate : File
{
    public override FileParameters Params {get { return ParamsImpl; }}
    protected abstract FileParameters ParamsImpl { get; }
}
public class SpecialFile : FileIntermediate
{
    public new SpecialFileParameters Params { get { return null; } }// TODO 
    protected override FileParameters ParamsImpl {get { return Params; }}
}

You can use generics to solve this:

    public class FileParameters   {    }

    public class SpecialFileParameters : FileParameters{}

    public abstract class File<T>
        where T : FileParameters
    {
        private T _params;

        public T Params   { get { return _params;}        }
    }

    public class SpecialFileParams : FileParameters<SpecialFileParameters> { }

and you will get the concrete "Special" when you access Params.

Is it necessary to have the same method name between the two methods (the override and the new method)? In these situations, I usually create a new method with a new name that returns the more derived type, and then have the override call this method in its implementation:

public override FileParameters Params { get { return SpecialParams; } }     
public SpecialFileParameters SpecialParams { get { return params; } } 

In this way, when you have a SpecialFile object, you don't need the cast. IF this doesn't work, perhaps you could explain more why you need the names of the methods to be the same for your situation.

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