Why can't I create a class in VB.NET that inherits System.IO.Directory? According to Lutz Roeder, it is not declared as NotInheritable!
I want to create a utility class that adds functionality to the Directory class. For instance, I want to add a Directory.Move function.
Please advise and I will send you a six pack. OK nevermind I'm not sending you anything but if you come to the bar tonight I will hook you up and then beat you in pool.
From the Meta Data of .NET
namespace System.IO
{
// Summary:
// Exposes static methods for creating, moving, and enumerating through directories
// and subdirectories. This class cannot be inherited.
[ComVisible(true)]
public static class Directory
You cannot inherit from a Static Class.
Are you using C# 3.0 VB.NET 2008 -- then you could add an Extension Method
If you use the DirectoryInfo class, you will have access to a MoveTo function.
EDIT: I'll correct myself... The static Directory class already has a Move method.
I'd guess that Reflector isn't picking up the sealed attribute correctly for VB (or perhaps just not displaying it properly). If you look at the IL, it is sealed:
class public abstract auto ansi sealed beforefieldinit Directory
Related
Say I have a class library project (Library) which contains a class of:
Public Class SomeClass(Of TTypeA, TTypeB)
Then, in another project UIProject in a different solution, I define a class that is derived from (inherits) SomeClass:
Imports Library
Public Class SomeDerivedClass
Inherits SomeClass(Of String, Boolean)
I have included Library.pdb and Library.xml alongside Library.dll (in the same folder) when I added the class libary reference to the UIProject.
Now, In UIProject I create a ClassDiagram (ClassDiagram1.cd), and add in the SomeClass class. So far so good.
The next step is to right-click on SomeClass in the diagram, and select "Show Base Class" from the dropdown. At this point, I am given the error:
Error HRESULT E_FAIL has been returned from a call to a COM
component.
If I do the same but for a non-generic version of SomeClass, then SomeClass is included in the class diagram, no problem.
No errors show up in ActivityLog.xml; nor in the Windows Event Viewer.
Is this a bug in Visual Studio (in which case I'll report it); or am I doing something wrong (and if so are there any other error logs or traces I can do to narrow down the issue further)?
The answer seems to be that COM does not work with generic types; and that it works in VS2017.
Not sure where to look for this. I want to make changes to a Silverstripe module I added to my site with composer but I don't want the custom code to be overwritten when I update the module at a later stage.
How can I make a few changes to some of the code without editing the core files? The code in question is in a function that is in a controller.
It definitely depends on your case.
If you want to add some custom methods use an Extension(see Simon's
answer)
If you want to add some database fields or relations, a DataExtension
is your friend
If the module is extensible and provides hooks, you
can change behaviour in your (you guessed it) Extension. Look for
$this->extend('functionName') in the module, you can modify stuff
in a method functionName() in your Extension
But sometimes it's a
bug or the module doesn't provide a hook you can use, then you have
to subclass the class and tell SilverStripe to use your Subclass instead:
class MySubClass extends SomeClass
{
public function doSomething()
$something = parent::doSomething();
//your changes
return $something;
}
}
You just need your changes and overwritten methods in your subclass, no need to copy all stuff in your subclass. This way you'll get most module updates later on.
Then you need to configure Injector to use your MySubClass instead of SomeClass in your config.yml:
Injector:
SomeClass:
class: MySubClass
You can make your own extension to it, e.g. class MyModuleExtension extends Extension
And override/edit/change code in there.
In your config.yml, register the new extension like so:
OriginalController:
extensions:
- MyModuleExtension
I'm just curious to know that there is the (Name) property, which represents the name of the Form class. This property is used within the namespace to uniquely identify the class that the Form is an instance of and, in the case of Visual Basic, is used to access the default instance of the form.
Now where this Default Instance come from, why can't C# have a equivalent method to this.
Also for example to show a form in C# we do something like this:
// Only method
Form1 frm = new Form1();
frm.Show();
But in VB.Net we have both ways to do it:
' First common method
Form1.Show()
' Second method
Dim frm As New Form1()
frm.Show()
My question comes from this first method. What is this Form1, is it an instance of Form1 or the Form1 class itself? Now as I mentioned above the Form name is the Default instance in VB.Net. But we also know that Form1 is a class defined in Designer so how can the names be same for both the Instance and class name?
If Form1 is a class then there is no (Static\Shared) method named Show().
So where does this method come from?
What difference they have in the generated IL?
And finally why can't C# have an equivalent of this?
This was added back to the language in the version of VB.NET that came with VS2005. By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type. Form1 vs frm in your snippet. There's history for that, VB didn't get classes until VB4 while forms go all the way back to VB1. This is otherwise quite crippling to the programmer's mind, understanding that difference is very important to get a shot at writing effective object oriented code. A big part of the reason that C# doesn't have this.
You can get this back in C# as well, albeit that it won't be quite so clean because C# doesn't allow adding properties and methods to the global namespace like VB.NET does. You can add a bit of glue to your form code, like this:
public partial class Form2 : Form {
[ThreadStatic] private static Form2 instance;
public Form2() {
InitializeComponent();
instance = this;
}
public static Form2 Instance {
get {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
}
return instance;
}
}
}
You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET. The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.
Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair. A problem when the abstraction is leaky. You are really better off not doing this at all.
VB is adding a load of code into your project behind your back, basically.
The easiest way to see what's going on is to build a minimal project and look at it with Reflector. I've just created a new WinForms app with VB and added this class:
Public Class OtherClass
Public Sub Foo()
Form1.Show()
End Sub
End Class
The compiled code for Foo looks like this when decompiled as C#:
public void Foo()
{
MyProject.Forms.Form1.Show();
}
MyProject.Forms is a property in the generated MyProject class, of type MyForms. When you start diving into this you see quite large amounts of generated code in there.
C# could do all of this, of course - but it doesn't typically have a history of doing quite as much behind your back. It builds extra methods and types for things like anonymous types, iterator blocks, lambda expressions etc - but not in quite the same way that VB does here. All the code that C# builds corresponds to source code that you've written - just cleverly transformed.
There are arguments for both approaches, of course. Personally I prefer the C# approach, but that's probably no surprise. I don't see why there should be a way of accessing an instance of a form as if it was a singleton but only for forms... I like the language to work the same way whether I'm using GUI classes or anything else, basically.
In my current project, a circuit drawing program, I'm deriving many classes from the same base class.
Public MustInherit Class clsCompo
Public Class clsRelay Inherits clsCompo
Public Class clsResistor Inherits clsCompo
Each child class has a 'getIcon' function that provides the desired image of the component. These get loaded in a listview to be used in the drawing program.
Is there an easy way to instantiated these classes to be used? Is there another way than manually instantiating each class? And then adding the image to the listview: something like:
Dim classes() As String = {"clsResistor", "clsRelay"}
Dim c(1) As Object
For Each cls As String In classes
c(1) = New cls
'add image to listview
Next
I'm using .NET 3.5
Thanks
If your classes have a parameterless constructor:
c(1) = Activator.CreateInstance(Type.GetType("MyNamespace." & cls))
Obviously, MyNamespace. should be replaced as appropriate.
You will need to use reflection and Activator.CreateInstance specifically to perform this trick. Going towards reflection path is dangerous, and usually brings more trouble than it gives benefits. In most cases there is a better way to design your application.
In your particular case, you could have a dictionary of icons, string to icon match, then just have a constructor of clsCompo specify the icon you want as a parameter. Unless you are using inheritance for something else, this should totally solve your problem, without the burden of using reflection.
I'm currently creating a class that extends UIComponent in Flex 3, but when the flash builder try to compile show me some errors
1044: Interface method createAutomationIDPartWithRequiredProperties in namespace mx.automation:IAutomationObject not implemented by class components:ArtWorkImage
1044: Interface method get automationEnabled in namespace mx.automation:IAutomationObject not implemented by class com.senocular.display:TransformTool
I see that UIComponent implements this interface, but I had never had this error before, I'm assuming UIComponent should made this implementation by default, so it should be something else, I already try to recreate the project or clean it, with no result, can someone please point me how maybe this can be fix, thanks for your help
oh btw I had this project before in flex builder, exported as a FXP and imported in Flash Builder, thanks!
All UI objects use an Automation delegate to handle implementation of the automation interface. Each UIComponent has a specific automation delegate registered with the Automation Framework. These automation delegate implementations are injected into the object by the Automation framework when the object is created according to the class name of the object.
For example:
UIComponent <- UIComponentAutomationImpl
ToolTip <- ToolTipAutomationImpl
DateChooser <- DateChooserAutomationImpl
Normally if you subclass a component you should inherit the Automation Implementation. However depending upon how the instances of the object are being created the automation framework may not be able to resolve the class name to the appropriate super class. In this case you may need to take additional steps to get the automation implementation into your class.
If you want your class to automatically be injected with a particulary automation implementation you should call the static registerDelegateClass method on the mx.automation.Automation class.
import mx.automation.*
Automation.registerDelegateClass(com.foo.bar.ArtWorkImage, mx.automation.delelegates.core.UIComponentAutomationImpl);
Alternatively you could directly implement the IAutomationObject methods in your UIComponent or create your own delegate class and instantiate and "inject" it into your class in its' constructor thereby by passing the Automation framework.
Here are few links that might help you understand the automation framework:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/automation/Automation.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/automation/delegates/core/UIComponentAutomationImpl.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/automation/package-detail.html