|
OK, I will provide a simple example about sorting collections, such as arrays, ArrayLists, etc.
The Array class has a static Sort method Array.Sort(Array) which is fine
when the array contains strings that you want sorted alphabetically. But maybe the items in the
array are not strings, or you need a special sort order.
The Array class also has a static Sort method where one of the overloads reads:
Array.Sort (Array, IComparer)
which means it needs an Array to be sorted, and an object that tells how to sort, by implementing
the IComparer interface, which defines a single method, like this:
int Compare (Object x,Object y)
Lets say my specific array contains objects of class Person which has a FirstName and LastName
property (bothpublic strings), and I want to sort them by LastName, and when equal by FirstName.
here is code that does exactly that:
class PersonSorter : IComparer {
public int Compare(object x1, object x2) {
Person p1=x1 as Person;
Person p2=x2 as Person;
int diff=string.Compare(p1.LastName, p2.LastName);
if (diff==0) diff=string.Compare(p1.FirstName, p2.FirstName);
return diff;
}
}
This is how we use the sorting object:
Person[] people=new Person[100];
Array.Sort(people, new PersonSorter());
Maybe in another occasion we have an ArrayList of Person objects, we can reuse the PersonSorter
to sort the ArrayList in the same way, since ArrayList too has a Sort method that takes an
IComparer to explain how to sort; this time its an instance method, so we would need:
myArrayList.Sort(new PersonSorter());
And later when we want to sort by FirstName first, we should create another class implementing
IComparer and pass an instance of that class to the Sort method of our collection.
The overall picture is: Array, ArrayList have been defined to work with IComparer (Microsoft
did not know about your Person class when they designed arrays and lists), all they care about
is the Compare method, so all you need to do is provide one; implementing an interface is
two things:
- providing the methods as specified in the contract
- telling the compiler you did so(by adding ": IComparer" to the class statement), so it can check things.
At first it may be surprising that we need a new class to explain how we want to sort; in fact,
we can add the Comparer method to an existing class. If there is only one way to sort the Person
class objects, we could add it in there. But sometimes it is wise to keep it separate.
On the other hand PersonSorter might contain more members and more methods, maybe it inherits
from another class (it could be a specialized Form, a calculator, whatever). As far as Array.Sort
is concerned, the only thing that matters is that it implements IComparer.
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Hi Jason.
An interface does not "provide" a method, as your previous messages indicate you think. Instead, interfaces say that "this method is required" - the programmer must provide it.
This is what is happening your case. The creators of the CAcroApp and CAcroAVDoc are not providing you with Open() and Exit() methods; they are saying you MUST write an Open method and an Exit method.
Why? Well, the example that helped me was the old standard - the Bank application. Imagine you have an application representing a bank. Obviously, it will need to handle accounts, so you create the Account class that has some basic methods like Deposit(int amt) , Withdraw(int amt) , and GetBalance() . Now your team of programmers can derive any new type of account they need to create from the Account class:
public class Savings : Account {...}
public class Chequing : Account {...}
public class LineOfCredit : Account {...}
public class BigBusinessExpense : Account {...}
Wonderful. But you have an issue. Banking regulations require that you be able to examine every account to make sure there have been no fraudulent transactions!
Your first thought is that you will create a CheckForFraud() method for the Account class. But this won't work: what constitutes a possible fraud in a Savings account (e.g. a withdrawal > $10,000) may be perfectly valid in BigBusinessExpense accounts. And your programmers are creating new types of Account classes every week. You can't possibly write a single piece of code to check for all the possible types of fraud!
Your second thought is that you will just tell your programmers they have to add a method that checks for fraud. But now, how do you make sure that they did it? And there is nothing stopping John from creating a bool Checking.CheckForFraud() and Mary from writing int LineOfCredit.FraudCheck() . How do you keep it straight so that you know that no matter which account type you are accessing you will always know how to check for fraud?
That is what an Interface can do for you.
public Interface IFraudCheckable
{
bool CheckForFraud ( date StartCheckingFrom, date EndCheckingAt );
}
Now all programmers should declare their Account classes as implementing the IFraudCheckable interface:
public class Savings : Account, IFraudCheckable {...}
public class Chequing : Account, IFraudCheckable {...}
public class LineOfCredit : Account, IFraudCheckable {...}
public class BigBusinessExpense : Account, IFraudCheckable {...}
Note: the IFraudCheckable interface does not "provide" the CheckForFraud method. It says if a class implements IFraudCheckable then the class MUST provide a CheckForFraud method that takes two date parameters and returns a bool result.
Now, John and Mary are forced to create CheckForFraud() methods for their accounts. And you are happy because you know that no matter what type of bank account your application is looking at, it can always call CheckForFraud() to make sure you are meeting banking regulations.
I hope that helps you understand what an interface is and what it is used for.
Also note: An alternative is to make the Account class implement IFraudCheckable . That way your programmers don't have to change their class declarations, since they already derive them from Account . This is perfectly valid, but it will require you to provide a "dummy" CheckForFraud() in the Account class. To make sure your programmers can't use this dummy method and have to write their own, you declare it as abstract .
public class Account : IFraudCheckable
{
...
public abstract bool CheckForFraud ( date StartCheckingFrom, date EndCheckingAt ) {};
...
}
Again, you don't provide any code in Account 's abstract CheckForFraud . The only reason you have one in Account is because you declared Account as implementing IFraudCheckable , and that means that Account MUST provide a CheckForFraud method that takes two date parameters and returns a bool result.
Clive Pottinger
Victoria, BC
modified on Wednesday, January 23, 2008 11:54:29 AM
|
|
|
|
|
Thank you both for your help and for taking the time to give it. I believe I've got a handle on the purpose of interfaces, however, I find them somewhat useless. I don't see why if my code works for my purposes, as in the code I provide in the methods I must implement such as open(), I even need the interface, other than the provider of the interface forcing me to utilize it if I chose to utilize their interoperability. I think a useful interface, for things such as opening a file, or showing a file, or opening an application, or closing an application, would provide methods that already provided that functionality based on specific parameters, such as a path string for a file location and name. In other words, if Adobe wants programmers who are utilizing their interop tool to be able to open a file the same way, consistently, every time( or check for fraud on a bank account), they would give a method that did just that and require you implement and use that. If it were something as abstract as fraud, which could be many things, the method being forced upon the user would limit you to checking for certain things, based on its' return value, or parameters, meaning it would be useless anyway if the fraud were something that couldn't be checked within the scope of that interface's forced implementation of a method. I just plainly don't see their usefulness.
|
|
|
|
|
I think I see your point, and both agree and disagree.
If I understand you correctly, you are saying that even though Adobe's use of an interface allows you create your own Open(), it still restricts what that method can do because it requires certain parameters be supported and only a certain type of result to be returned. Just as the IFraudCheckable interface limited the programmers to a boolean result.
True enough.
But is better than the Adobe guys forcing their idea of what Open() should do on you. Perhaps I have decided that Open() should open an XML document, find a tag with a URL in it and retrieve the file to be opened from there. No doubt no one at Adobe ever thought anyone would want to do that, and if they created the Open() method themselves, then I could never implement my "XML-based user-specific open-web-file" idea. Perhaps that is a silly example, but the idea is there: "we want something done, but we want our users to be able to decide how it is done".
Clive Pottinger
Victoria, BC
|
|
|
|
|
Wouldn't your example still be allowed if they specified what Open() meant? I mean, open would just open the document, the same way, every time, that shouldn't and doesn't eliminate a user from manipulating the app, or active doc once open...or does it... maybe it doesn't even matter. I've come to terms with interfaces. This site is excellent for intelligent input and I think my personal dislike of interfaces is not worth the time of any of us. But thank you all again for your help.
Jason
|
|
|
|
|
I feel like a monkey's ass. I get it now. I really really get it. Thank you all for your help.
I've never overcomplicated something so bad in my life. simple, almost too simple. wow....
Jason
|
|
|
|
|
Hi everybody,
I have a program that creates an image on a bmp image on mouse click and puts it in the point of clicking, just like "etap" program does.
THE PROBLEM IS
How can I save this big picture, which contains those small images, to a single file so that it opens automatically using my application when the user double click on it??
please I need URGENT help.
thanks in advance>>>
|
|
|
|
|
AliNajjar wrote: please I need URGENT help
That is rather rude.
AliNajjar wrote: just like "etap" program does
What program is "etap"?
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
|
|
|
|
|
Thanks anyway for your reply
etap is a program used for solving electrisity issues and problems
like load flow problem, using some mathematical equations and methodes like Newton-Raphoson for example..
I hope this reply would be useful and I hope to hear from you soon..
Thank you again>>
|
|
|
|
|
Use the BitBlt[^] windows API functions to copy the content of the screen into an image, then save and load the image as appropriate.
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Sorry Man,
I dont think this may work because
I need or want to change the location, as well as the parameters
of any image on the screen, so can you say this might help>>
thanks ..
|
|
|
|
|
Oh, I see. You need to keep a list of points and images, then serialize this list to the file when your user exits. On startup, load this file, deserialize the contents, then iterate through the list loading the images on the screen where appropriate. If the images can be layered, then the order of the list is important on serialization. Hope this helps,
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Actually it does help.,, But
What I was trying to do is to retrive the name and position of every image
and save those info to a file,, let's say like this.
imgName imgPos
img1 20,20
img2 45,75
...
imgk xx,yy
So what we may want to do is
When exiting the program or saving it, save this file to the project folder the user creates
and then, when the user opens it again.. the program will create those images in the order they are saved in...
But the problem remains although I have got the Idea
I still don't know how to do so...
Thank you for your help.
|
|
|
|
|
1. Create a class that is serializable to hold your data
[Serializable]
public class ImageInfo {
public ImageInfo();
public ImageInfo(string fullPath, int x, int y);
public string Path { get; set; }
public Point Location { get; set; }
} 2. Create a stack of those objects, and push/pop items to the stack
private Stack<ImageInfo> m_Stack = new Stack<ImageInfo>();
...
m_Stack.Push(new ImageInfo(imagePath, 50, 50));
...
ImageInfo old = m_Stack.Pop(); 3. Serialize the stack of objects to a file
using (FileStream fs = new FileStream("yourFilePath", FileMode.Create, FileAccess.Write
, FileShare.None, 0x1000, FileOptions.Encrypted | FileOptions.SequentialScan) {
new BinaryFormatter().Serialize(fs, m_Stack.ToArray());
} 4. Deserialize the stack from a file
using (FileStream fs = new FileStream("yourFilePath", FileMode.Open, FileAccess.Read
, FileShare.Read, 0x1000, FileOptions.Encrypted | FileOptions.SequentialScan) {
m_Stack = new Stack<ImageInfo>((ImageInfo[])new BinaryFormatter().Deserialize(fs));
} I'm not sure if there is a 'ToArray' Method on stack or not, nor do I know if there is a constructor for stack which takes an array, but you get the idea. Good luck.
Sounds like somebody's got a case of the Mondays
-Jeff
|
|
|
|
|
Thanks so much,.
I am gonna try it and see what it would result into.
But.. Do you think there may be a better idea than the one I came up with.
Please enlighten my brain man.
Thank you....
|
|
|
|
|
Hello,
I'm needing write some Java/C# interop code and I'm wondering if anyone here has experience in this area and could provide a few tips.
I understand there are tools that allow you to register Java components as COM objects. This allows you to solve the problem with COM interop. Is this the best way to go? Are there any other great ideas?
Thanks!
|
|
|
|
|
This whole multi-threading structure keeps shifting in and out of focus like a Dali painting after 5 pints of Guinness...
Okay, I have the following going in my OldMcDonald process:
PanickyChicken chickenLittle = new PanickyChicken();<br />
<br />
Thread t = new Thread(new ThreadStart(chickenLittle.WanderAbout));<br />
t.Start();<br />
while ( !t.IsAlive );<br />
<br />
this.WaitForAcornToDrop();<br />
...
Now, once the WaitForAcornToDrop method has executed, I want to get my chickenLittle thread (t) to execute its WarnAll method [e.g. chickenLittle.WarnAll("The sky is falling");]
How do I tell an executing thread to perform a task?
Clive Pottinger
Victoria, BC
|
|
|
|
|
Hi,
a thread executes whatever code is passed to it at creation time, in your example it will run
the WanderAbout() method until that method is done. So whatever you wnat the thread to do must be
inside that method, you can't make it suddenly do something completely different.
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
In addition to what Luc said, you can influence what's happening inside your thread's procedure for example by setting properties of your object which in turn are used inside the thread procedure.
For example, your PanickyChicken class could have a property
public bool ThinksSkyIsFalling = false {get; set;} (don't know if that's the correct C# 3.5 syntax, but I think you get the idea).
Now your chicken is wandering about until your program tells it that the sky is falling:
chickenLittle.ThinksSkyIsFalling = true; Now inside your WanderAbout method you can execute the WarnAll method as soon as ThinksSkyIsFalling==true and then exit WanderAbout - chickenLittle's job is done.
But then you'll have to think about synchronization issues. In the example above I think there's not much that can go wrong without explicit synchronization, but when you're performing operations that can be interrupted by a thread switch, you'll definitely have to take care of these cases. The lock() instruction can come handy in these cases.
Regards,
mav
--
Black holes are the places where God divided by 0...
|
|
|
|
|
Thanks Mav.
I think you hit the root of my question - is a reference, in my main thread, to chickenLittle.ThinkSkyIsFalling valid even though chickenLittle is operating in thread t ? It appears it is - great.
That gives me the groundwork I needed to get information to my executing thread.
Thanks again.
Clive Pottinger
Victoria, BC
|
|
|
|
|
Hi.
I have a problem in XNA; it's that I want to have several sprites of the same thing, except place them in different places while keeping the 'physics' they all have. Can anyone give me a general idea of how I might do this. (Please try not to be too technical, unless it's needed!) If it helps anyone understand better, I'm making a border around the edge of the form with the boxes, but then I also want to draw 5 more inside various places. Please help, thanks!
+I tried making the Texture2D into an Array and in the Load method, making a for loop to load a certain amount, but that doesn't work. That was my idea... Partly... Help is still appreciated.
+Actually, I'vr got the hang of it. Stupid mistake... But any more info would still be liked. Thanks, kind of.
- I love D-flat!
modified on Tuesday, January 22, 2008 6:01:45 PM
|
|
|
|
|
Glad to hear you figured it out.
In future it would be better if you posted your XNA related questions here.
You will get much quicker and better answers - mainly because the guys/girls who wrote the XNA framework maintain, and actively contribute to the forum.
Cheers,
Mark.
|
|
|
|
|
How do I go about playing 24-bit wav files? I have 8 and 16 bit wavs playing fine with directsound, but when I run a 24-bit file through the same code I get a not-so-helpful crash ("Value does not fall within the expected range.") when trying to create a new SecondBuffer instance (sound = new SecondaryBuffer(dataGridResults.CurrentRow.Cells[3].Value.ToString(), d, dSound);).
I have searched high and low for answers, but the most I can come up with is something to do with WAVEFORMATEX or WAVEFORMATEXTENSIBLE. Although I don't know how to go about using them.
|
|
|
|
|
I have a C# solution with 2 projects, a test form in one project and a DLL in another. The DLL connects to a socket and sends and receives messages to and from the test application using properties in the DLL.
How does one send an event, such as poll events of the socket, to the test application? I want to know if the connection was dropped, when it was dropped, and set a button to red when connection is lost.
Very new to C# and I hope I framed the question well enough to get an answer.
Thanks in advance,
Joe
|
|
|
|
|
Hi All,
I can create appointments in MS Outlook via my c# application, bud how can i now remove or update this appointments?
thanx
|
|
|
|
|