Overriding an internal abstract method in another assembly - c#

Im currently working on a c# project that uses another .net library. This library does (amongst other things) parse a sequence into a tree. All items are of some type that inherits from the abstract class Sequence. I needed to alter the behaviour slightly and subclassed Sequence myself (lets call it MySequence). After the tree was created, I could replace some tree nodes with objects of my own class.
Now, a new version of the library was published, and a Copy function with the following signature was introduced:
internal abstract Sequence Copy();
I tried to adopt my code to the new version and override it, but whatever I am doing, I get the two errors:
MySequence does not implement inherited abstract member 'Sequence.Copy()'
and:
MySequence.Copy()': no suitable method found to override
This makes sense, since it is abstract (--> it must be overwritten) and internal (--> it can not be overwritten, due to hidden visibility from outside the assembly)
So, the problem is, I understand why this is happening, but dont know what to do against it. It is crucial for my project to subclass Sequence.
And what I also dont understand is, why the internal abstract modfier is allowed in the first place as it basically permits any subclassing of the whole class from outside the assembly!?
Is there any way to solve this? Via reflection or something?
Thanks in advance!

Basically, you are out of luck without altering the library. There may be a subclass of Sequence that does implement Copy, which you can derive from in the new version. But it is likely that the Copy method is need in other parts of the library to create clones.

This modifier means that the class can only be inherited in the assembly that defined it.
There is no way around that.

If a library has a type with a member with the modifiers internal abstract, I conclude that the developers of that library didn't want anyone to derive their own type from that type. You cannot work around this.
You can consider whether this was done deliberately. You should ask the publishers. It might be a mistake, in which case the publishers will probably issue a fix. If it is done deliberately, you should come up with an alternative solution without deriving from that type.
EDIT: Or perhaps they intended for you to derive only from derived types in the same assembly that already implement that member.

Related

How can I prevent methods from being added to a class?

I'm trying to find out if there's a way to stop functions/methods from being added (EDIT: by other developers) to a class for the case where the object is a Model or DTO which should not contain methods (to prevent 'abuse' of the Models/DTOs by others, who may try and add 'helper' methods etc).
Is there any way to achieve this?
Use reflection and write a unit test that fails if a model-class has methods.
Mark all you model classes with a custom attribute. Then make a unit test that uses reflection to load a given assembly, iterate all classes in that assembly and check that classes marked with the model attribute does not have methods. This should be fairly straight forward using reflection.
I believe you are trying to solve a procedural issue with code where you should be using communication.
Your colleagues (i assume) are operating on the code files with 'full trust' privileges. If they break that privilege you should open a dialogue. Use the change as an opportunity to educate them on the intended design. Perhaps they are correct and you will be educated!
I suggest simply making the intended design obvious in the class name and with a comment stating the intended nature. Perhaps quote the design document(s) that informed the class.
You cannot hinder anyone with full write-access to your code-base to do so. The only two things you may do to avoid it are create some CodeAnalysis-rule for FXCop as mentioned by Christian.K in the comments or by writing your DTO-class so that it is undoubtly a DTO that should not have any methods by using a unambigious name for the class and if this is not enough provide some code-comments that notifies the coder to do not so.
However you may need some kind of method if using collections e.g. where you will need some kind of comparision if two instances of your DTO are equal, so you have to provide at least an Equals- and GetHashCode-method.
You don't need to use a struct to prevent additions to a class. You can use the sealed keyword
public sealed class MyDTOObject { ... }
Now, you can not inherent a class and also prevent inheritance (which is essentially what you're asking). The very fact of inheriting MyDTOObject is creating a new class which is based off of not equal to, or restricted, or defined in any way by the implementation of MyDTOObject.
You can use an abstract class, to force derived classes to implement certain methods, but not the other way around.
If you want to prevent others from deriving from your class and implementing helper methods, you must use the sealed keyword, or mark the class internal.
You may prevent the class being extended or inherited by marking it final that way nobody would be able to extend your class and hence not being able to add any behavior. But stop and ask yourself whether you want to do that or not, because then you'd be signing an invisible contract that everything ever required by the class is written in the class and this class needs no further addition.
To be clear, I was talking in Java context.

Remove Interface Members from Implementation when Interface Changes

Situation:
I implement an interface implicit and remove a property on the interface (later).
There is no warning that this property should be removed on the implementation class.
I know I could implement the interface explicitly, but I would try to go around that.
EDIT: (added a question)
How can I be notified/warned/... that I maybe no longer need the member in the implementing class?
There is no way the compiler can give you such a warning in C#. It would somehow need to have knowledge of past versions of the interface to know what method/property was removed and therefore identify possible candidates for removal.
And answering your commentary, you can not make the compiler / refactoring tool decide if any given method is a candidate simply based on the #region its defined in. There is absolutetly nothing that enforces any given method to be defined in any given region, its just visual sugar so refactoring based on regions would be completely unsafe.
Sometimes verbose languages do have advantages, and in this case VB with the implements keyword would make this a compile time error. In C#, you have to use explicitly implemented interfaces which is not a bad option at all. Read here for more details.

How can I determine at runtime if an interface member is implemented?

I have an interface called IStructuredReader that reads some structured data from a file and displays it in a form. It has a member called Sync() that, when implemented, scans the data for a user-specified data pattern.
Some implementations of IStructuredReader don't have sync capability. Those implementations throw NotImplementedException for the Sync() method. I would like to be able to check for this method being implemented, so that I can dim the button on the form if it is not.
I can think of a number of ways that this could be done, all of which seem clumsy and complicated:
Separate the Sync method into its own interface, inherit it for those implementations that support the capability, and attempt to cast the reader object to it to identify the capability,
Write a NotImplementedAttribute, decorate the member with it, and check for the presence of the attribute using Reflection,
Add a HasSyncCapability boolean property to the interface.
Is there a canonical way this is done?
This sounds like you really should have two interfaces. Your Sync() method is obviously adding functionality over your base interface, which suggests that this is really a separate concern, as it's not a requirement of IStructuredReader. I would suggest adding a second interface for the types which support this, which would then be easy to check for in your view layer.
The canonical way is for the interface to expose the methods that will be implemented, so the cleanest solution I see is to create another interface called maybe Syncronizable with just that method. If your object implements that interface you know the method is there, and this is not clumsy at all. Using reflection or the extra attribute are indeed not as clean as solutions, but it doesn't mean you shouldn't go for those if it makes your life easier ;)

Hide class members from everything except another specific assembly

I have two class libraries "MyLibrary.dll" and "MyLibraryEditor.dll" for a Unity runtime and editor extension. There are several class members inside "MyLibrary.dll" that are only intended for use by "MyLibraryEditor.dll".
My first thought was to use the internal keyword because I mistakenly thought that this constrained visibility to a namespace. Instead it is clear that this keyword limits visibility to the assembly.
What is the best way to constrain access to some class members to "MyLibrary.dll" and "MyLibraryEditor.dll" without hurting performance? Also, reflection is not an option.
I am happy to simply not document the functions, but unfortunately Intellisense (and MonoDevelop's equivalent) show these members.
If you want internals in one assembly to be visible from another assembly, you can use the InternalsVisibleTo attribute on the assembly containing the internals. See http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx:
[assembly:InternalsVisibleTo("MyLibraryEditor")]
That answered, you might want to rethink your architectural design so that you don't need to use it, since it will open up all internals to the other assembly, not only the ones that you want.
You could make the members internal but use [InternalsVisibleTo] to give access to those members to the other assembly. They'd still be visible within the same assembly as well, of course... there's no way of getting round that.
I primarily use InternalsVisibleToAttribute for giving access to internal members to test classes, and would try to avoid doing this for non-test purposes - but sometimes it can be useful.
This is not possible using pure C# concepts. You are two seperate assemblies, that is as far seperate as you can get, and there is no relationship between the two as far as .Net is concerned.
you could do some things with signing or validation to make it so it would be difficult to use one assembly without the other, but not something you can do to prevent visibility of the classes/members.

Internal property and subclassing

I think it is by design and there is nothing can be done about it, but I found it interesting.
I needed to create a concreate class based on third-party abstract base class. As always, I told Visual Studio to implement abstract base class, which it did, but the code didn't compile complaining about missing getter. However, event after adding getter manualy, the code still didn't compile. It turned out that this getter is internal. Funny thing about internal property is that it's not shown in metadata (View Definition). Vendor will make it protected in the next release, but at the time being, unless I'm missing some other way, there is nothing I can do about it, right?
-Stan
That's correct.
In fact, we basically do the same thing in Noda Time where we want to expose a type (CalendarSystem) so that clients can pass calendars around - but all the actual interaction is internal to the library, using other internal types. What you've got as a problem in your situation is actually a blessing in ours, as it means we can keep more of the implementation internal and hidden :)
It's harder to do the same thing with interfaces...

Categories

Resources