|
Mike-MadBadger wrote: I'm struggling to follow this explanation myself I tried twice, and got lost twice. Let's try it differently; you've seen how the different events in .NET all look similar, with two parameters? One could do something similar;
Public Class MyParamaterBase
Public Property Id As Guid
End Class
Public Class MyExtendedParameter
Public Property Title as String
End Class
Public Class SomeConsumingClass
Public Sub SomeMethod(TheParameter As MyParameterBase)
If TheParameter is MyExtendedParameter Then
Console.WriteLine((TheParameter as MyExtendedParameter).Title)
EndIf
End Sub
End Class
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Ok, so instead of an Enum parameter I have a base class parameter which through polymorphism can take a derived type which carries the extra parameter information?
I guess I could do the same thing by using an interface as the parameter?
Thanks,
Mike
|
|
|
|
|
Mike-MadBadger wrote: I guess I could do the same thing by using an interface as the parameter? Yes
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I think this is simply a variation on your suggestion (in effect), using a nested class.
Public Class Class1
Private _param As Double
Public Sub New(ByVal amount As Double)
Me._param = amount
End Sub
Public Property Param() As Double
Get
Return Me._param
End Get
Set(value As Double)
If Not value = Me._param Then
Me._param = value
End If
End Set
End Property
Public Function ToGrey() As ToGreyMethods
Return New ToGreyMethods(Me)
End Function
Public Class ToGreyMethods
Private _outer As Class1
Public Sub New(ByRef outer As Class1)
Me._outer = outer
End Sub
Public Sub Increase(ByVal amount As Double)
Me._outer.Param += amount
End Sub
Public Sub Decrease(ByVal amount As Double)
Me._outer.Param -= amount
End Sub
End Class
End Class
Module Module1
Sub Main()
Dim thing As Class1 = New Class1(10)
thing.ToGrey.Increase(5)
Console.WriteLine(thing.Param.ToString())
thing.ToGrey.Decrease(10)
Console.WriteLine(thing.Param.ToString())
Console.ReadKey()
End Sub
End Module
My only problem with this is that I can't seem to hide the nested class so one could be created at runtime manually rather than as a result of a call to ToGrey(), which starts to feel a bit messy or at least has the potential to get messy since I do.t know what would happen if, for example, you could do this.
Public Sub Example()
Dim thing as Class1 = New Class1(10)
Dim whoops as ToGreyMethods = thing.ToGrey()
End Sub
|
|
|
|
|
Mike-MadBadger wrote:
The effect would also be there without the new object; any object that's embedded in a property can be put in a variable, and one can manipulate the referenced object without looking at whose property it was.
Public Class Class1
Private _param As Double
Private _methods As ToGreyMethods
Public Sub New(ByVal amount As Double)
Me._param = amount
Me._methods = New ToGreyMethods(Me)
End Sub
Public Property Param() As Double
Get
Return Me._param
End Get
Set(ByVal value As Double)
If Not value = Me._param Then
Me._param = value
End If
End Set
End Property
Public ReadOnly Property ToGrey() As ToGreyMethods
Get
Return _methods
End Get
End Property
Public Class ToGreyMethods
Private _outer As Class1
Public Sub New(ByRef outer As Class1)
Me._outer = outer
End Sub
Public Sub Increase(ByVal amount As Double)
Me._outer.Param += amount
End Sub
Public Sub Decrease(ByVal amount As Double)
Me._outer.Param -= amount
End Sub
End Class
End Class
Module Module1
Sub Main()
Dim thing As Class1 = New Class1(10)
thing.ToGrey.Increase(5)
Console.WriteLine(thing.Param.ToString())
thing.ToGrey.Decrease(10)
Console.WriteLine(thing.Param.ToString())
Dim whoops As Class1.ToGreyMethods = thing.ToGrey()
Console.ReadKey()
End Sub
End Module
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
BTW, I'd give a +5 but there's no option to do so
|
|
|
|
|
<- It's hidden
|
|
|
|
|
Use a definition object. That is passed to the second object and defines how it runs. The definition object can provide things like a default definition, common definitions, common ways to create definitions and custom definitions.
|
|
|
|
|
Unfortunately I'm not sure exactly what a definition object is and Google hasn't helped, could you possibly help me with a link or a bit more explanation?
|
|
|
|
|
pseudo code
pre>
Object Def
ByVal method As RGBGreyScaleMethod;
ByVal factors as LumaEnum;
...
Object Implem
Doit(Def def)
|
|
|
|
|
It looks like you found a solution that you are happy with, but I thought that I would throw my 2 cents worth into the fray.
Based on my understanding of your code, the Luminosity method is the only one that needs a second parameter. Why not remove Luminosity from your methods enum and change:
Public Overloads Sub ToGreyScale(ByVal method As RGBGreyScaleMethod, ByVal factors as LumaEnum)
to:
Public Overloads Sub ToGreyScale(ByVal factors as LumaEnum)
I think that this would given you the intuitiveness factor that you are seeking.
As I don't know what it all is that you are doing in this "Class" the following may not be relevant, but I will throw it out as an alternative. It appears that all you are using it for is to convert a Color structure to its equivalent greyscale color. Perhaps, this may be a case for using extension methods to the Color Structure.
Module GreyScaleExtentions
Public Enum RBGMethods
Average
BlueChannel
Decompose
Desaturate
Lightness
RedChannel
GreenChannel
End Enum
Public Enum LumaEnum
BT709
BT601
GIMP
End Enum
''' <summary>
''' Converts Color to greyscale equivalent using RGBGreyScaleMethod
''' </summary>
''' <param name="c"></param>
''' <param name="RGBMethod"></param>
''' <returns></returns>
''' <remarks></remarks>
<Runtime.CompilerServices.Extension()> _
Public Function ToGreyScale(ByVal c As Color, ByVal RGBMethod As RBGMethods) As Color
End Function
''' <summary>
''' Converts Color to greyscale equivalent using luminosity method
''' </summary>
''' <param name="c"></param>
''' <param name="factors"></param>
''' <returns></returns>
''' <remarks></remarks>
<Runtime.CompilerServices.Extension()> _
Public Function ToGreyScale(ByVal c As Color, ByVal factors As LumaEnum) As Color
End Function
End Module
Then you could use like this:
Sub test()
Dim c As Color = Color.FromArgb(230, 134, 231, 10)
Dim gs As Color
gs = c.ToGreyScale(LumaEnum.BT601)
gs = c.ToGreyScale(RBGMethods.Average)
End Sub
|
|
|
|
|
That one had occured but it meant that a user of the class would need to know that the overload without a method would give ByLuminosity, which was the bit that felt unintuitive.
BTW, thanks for the <Runtime.CompilerServices.Extension()> piece, I assume that's how extension methods work?
I might add those to extend the Color type to include the functionality in my RGB and aRGB types, thanks.
|
|
|
|
|
Quote: That one had occured but it meant that a user of the class would need to know that the overload without a method would give ByLuminosity, which was the bit that felt unintuitive.
The issue of being intuitive is very subjective. I see the intuitive part being to use the "ToGreyScale" method and even that may require some explanation. At some point a programmer has to demonstrate some competence and look at the provided documentation. This is the reason that I showed the visual studio intellisense support using xml comments in the code I posted (see: Documenting Your Code With XML Comments). Providing this documentation is your responsibility as the developer and you should not be relying on something being intuitive as a substitute for proper documentation. Paste the extension method code I provided into a project and observe the intellisence pop-ups when you try to use the defined methods.
Quote: BTW, thanks for the piece, I assume that's how extension methods work?
Assume nothing when coding. Use your friendly search engine and research it yourself. I have found that this general query works well in the major search engines:
msdn TopicYouWant -social"
The reason for the "-social" is to try to eliminate results from the msdn help forums and to focus on the documentation pages.
So much for my preaching for the day, have a good weekend.
|
|
|
|
|
Thank you. My code is XML commented I just left it out of the simplified examples here. For the extension methods I'm not sure why I left the question in, I had searched Google, guess I was just looking for confirmation - probably not necessary.
On the structure, I agree but something feels clunky, nevermind.
Have a nice weekend
|
|
|
|
|
I have an DLL assembly that is used by many other apps. This assembly is likely to change as new requirements are discovered.
Now, let's say the referencing apps are all running, I change the code in the dll for a new app, and then start the new app.
What I'm seeing is that the new app uses the version of the assembly that's already in memory. Is that an accurate statement?
If so, is there a way to force the new app to use the copy of the dll that it was linked to instead of using what's already in memory?
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass." - Dale Earnhardt, 1997
|
|
|
|
|
The running application (or new application using currently cached DLL) doesn't know about changes to the DLL itself in most cases, so you'd have to write some kind of polling thing, or event response to the Windows file changed event, and pick up the new DLL and link it in "manually" like this...
Assembly assembly = Assembly.LoadFrom("MyLibrary.dll");
Type type = assembly.GetType("MyType");
object instanceOfMyType = Activator.CreateInstance(type);
This is frustrating for sure, when you have lots of apps using the same DLLs - I've had this issue with multiple web sites before, and it took us a long time to understand what was happening. You would think that copying over the old DLL would cause a system-wide "this DLL is no longer up to date" kind of event, but apparently not.
|
|
|
|
|
I tried using strong naming, but that had no effect.
WTF good is code re-use if I can't actually re-use the freakin code in compiled form?
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass." - Dale Earnhardt, 1997
|
|
|
|
|
Yeah it's not ideal. Sometimes you have to re-start the server. I think they opted for making it harder to use the wrong assembly instead of easier to manipulate which ones are used.
|
|
|
|
|
John Simmons / outlaw programmer wrote: ...by many other apps.
What do you mean by "app"? Or more specifically how many process spaces are you running into which these apps appear?
An executable/service has a load dynamic that, excluding GAC, will load based on several factors but the primary one is the current working directory of the primary executable. A new process space will load a new copy of the dll that it found doing an assembly search. It doesn't have anything to do with what other processes have loaded into memory.
Now if you are messing with AppDomains and changing the loading semantics then that alters how it searches and that would alter where it looked. The process would still load a new copy though.
John Simmons / outlaw programmer wrote: What I'm seeing is that the new app uses the version of the assembly that's
already in memory. Is that an accurate statement?
Not in general, but as noted it depends on what you mean by "app". The process (AppDomain) loads the dll into memory. It won't load it again, but every process gets one (I can't remember if there is AppDomain chaining or not.)
|
|
|
|
|
Sure that's what should happen, but I've seen a DLL basically get "locked" on the whole machine, and even though we replaced the DLL itself, the old behavior continued until we shut down the web server. This was on a web site where several sites used the same ORM assembly, and it appeared that IIS was loading one copy of the DLL for everybody, and it refused to let go of that even when the underlying file was DELETED. We had different app pools for each site, so it was really unexpected. I would have thought it was impossible, actually.
Pretty sure that's what he's talking about happening, and I agree it shouldn't happen, particularly when he said he starts a new copy of the app. It completely baffled me and a few guys in India - we couldn't figure out what was going on, and after that night(!) it became standard procedure to re-start the web server after rebuilding the ORM assemblies.
|
|
|
|
|
Jasmine2501 wrote: and it appeared that IIS was loading one copy of the DLL for everybody, and it
refused to let go of that even when the underlying file was DELETED
IIS is a process. It (presumably) uses AppDomains but that goes back to whether chaining is involved.
And per the docs chaining can happen at least with the default AppDomain.
And of course if chaining is involved then deleting the dll would have no impact - if .Net finds the assembly in memory (within the Process/AppDomain context) then it doesn't load it again.
|
|
|
|
|
If you want to keep both the new and the old dlls, you can use something called a Publisher Policy.
This would allow you to use the new dll. If you want to use the old one just set the publisher policy setting off.
More here[^].
|
|
|
|
|
Hi,
I am looking for an event to hook into that occurss after aform has been created, but, before the form is displayed. In MFC I would use OnInitDlg().
My Main Window is essentially aSplash Screen. I want to display a LogIn Screen op top of that.
If I do that in the constructor, the login box isnaturally displayed first, followed by the splash screen. The Splash Screen does not create events to hook into.
Furthermore, How do I call the Base Class version in a handler I override. Below is how I woulddo thisin CPP. but this code will not compile in C#.
namespace SgCntr
{
public partial class MainWnd : Form
{
protected override void OnXXX(EventArgs e)
{
Form::OnXXX(e);
LogOn logon=new LogOn();
DialogResult dlgres=logon.ShowDialog(this);
}
}
}
Bram van Kampen
|
|
|
|
|
|
Hi,
Thanks.
The MSDN Ref you point me to is quite sparse, and does not realy cover the topic. (it covers events sent by a button click. It purports to document the Load event, but is silent about this in it's explanations)(not your fault, I blame Steve Balmer). I'd say a lot is missing. primarily the 'HowTo' hook into a 'Load'event. To prove the point, I did as the sample specified, and pasted the code in to a form, according to instructions. Unsurprisingly, nothing happened when the button was clicked. In MFC terms, the message map entry is missing, in SDK terms, the message is not intercepted in the WndProc, I suppose, in .NET terms, the handler delegate has in the example, not registered with the event.
Kind Regards,
Bram van Kampen
|
|
|
|