tags:

views:

227

answers:

7

I have been scratching my head over this for days and I still cannot understand how to implement this interface.

Here is my code:

namespace ConsoleApplication32 {
public static class ScanAndSerialize
{

    public static void Serialize()
    {

        List<string> dirs = FileHelper.GetFilesRecursive("s:\\");
        List<string> dirFiles = new List<string>();
        foreach (string p in dirs)
        {
            string path = p;
            string lastAccessTime = File.GetLastAccessTime(path).ToString();
            bool DirFile = File.Exists(path);
            DateTime lastWriteTime = File.GetLastWriteTime(p);
            //dirFiles.Add(p + " , " + lastAccessTime.ToString() + " , " + DirFile.ToString() + " , " + lastWriteTime.ToString());
            dirFiles.Add(p);
            dirFiles.Add(lastAccessTime);
            dirFiles.Add(DirFile.ToString());
            dirFiles.Add(lastWriteTime.ToString());
            dirFiles.Add(Environment.NewLine);

        }


        XmlSerializer SerializeObj = new XmlSerializer(dirFiles.GetType());
        string sDay = DateTime.Now.ToString("MMdd");
        string fileName = string.Format(@"s:\project\{0}_file.xml", sDay);
        TextWriter WriteFileStream = new StreamWriter(fileName);

        SerializeObj.Serialize(WriteFileStream, dirFiles);
        WriteFileStream.Close();


    }

    static class FileHelper
    {
        public static List<string> GetFilesRecursive(string b)
        {
            // 1.
            // Store results in the file results list.
            List<string> result = new List<string>();

            // 2.
            // Store a stack of our directories.
            Stack<string> stack = new Stack<string>();

            // 3.
            // Add initial directory.
            stack.Push(b);

            // 4.
            // Continue while there are directories to process
            while (stack.Count > 0)
            {
                // A.
                // Get top directory
                string dir = stack.Pop();

                try
                {
                    // B
                    // Add all files at this directory to the result List.
                    result.AddRange(Directory.GetFiles(dir, "*.*"));

                    // C
                    // Add all directories at this directory.
                    foreach (string dn in Directory.GetDirectories(dir))
                    {
                        stack.Push(dn);
                    }
                }
                catch
                {
                    // D
                    // Could not open the directory
                }
            }
            return result;
        }
    }



    public class MyInterface: IValidationRowSet
    {

        public int RowNumber { get; set; }

        public string RowAsString { get; set; }
        public IValidationRowSet MatchedRow { get; set; }
        public string FriendlyNameLabel { get; set; }
        public string KeyFieldLabel { get; set; }
        IList<string> lst = new List<string>();
        public string SourceWorksheetName { get; set; }
        public string SourceRangeName { get; set; }
        //public string SourceRangeName { get; set; }
        public bool bReported { get; set; }

        public int FieldCount { get { return lst.Count; } }
        public string FieldData(int id)
        {
            if (id <= lst.Count)
                return lst[id];
            else
                return null;
        }
        public string ValidationMessage { get; set; }




    }

Here is an explanation of the interface (still scratching my head over this one)

namespace Validation {
/// <summary>
/// Implement this interface if you want the engine to callback when it finds exception
/// messages.  You will pass a reference to you class to the validation engine, and 
/// it will call "PostValidationMessage" for each exception example, including the message,
/// the entire row set of data (vr), and the id of the field that created the exception.
/// </summary>
public interface IValidationReporter
{
/// <param name="sMsg"></param>
/// <param name="vr"></param>
/// <param name="id"></param>
    void PostValidationMessage(string sMsg, IValidationRowSet vr, int id);
}


/// <summary>
/// Implement this interface in order to use the validation engine.
/// The validation engine takes 2 IList<IValidationRowSet> objects and compares them.
/// A class that implements this interface will contain an entire row of data that you'll
/// want to compare.
/// </summary>
public interface IValidationRowSet
{

    /// <summary>
    /// should return an int of the number of fields in this row
    /// </summary>
    int FieldCount { get; }

    /// <summary>
    /// should return an int of the row number that this row is in the set
    /// usually set when the data is assembled
    /// </summary>
    int RowNumber { get; set; }

    /// <summary>
    /// this is a function that should return the field data for this row at zero-indexed location "id"
    /// ex: if the row contains this data: smith|fred|2126782524|[email protected]|
    /// a call on this method of FieldData(2) will return the phone number 2126782524
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    string FieldData(int id);

    /// <summary>
    /// this will be modified by the validation process
    /// </summary>
    string ValidationMessage { get; set; }

    /// <summary>
    /// this will be modified by the validation process
    /// </summary>
    IValidationRowSet MatchedRow { get; set; }

    /// <summary>
    /// returns a string that uniquely identifies this row
    /// ex: if the row contains this data: smith|fred|2126782524|[email protected]|
    /// so for this example, the unique identifier could be the email address [email protected]
    /// </summary>
    string KeyFieldLabel { get; set; }

    /// <summary>
    /// returns a string with the "friendly" name of this row
    /// ex: if the row contains this data: smith|fred|2126782524|[email protected]|
    /// so for this example, FriendlyNameLabel could be the name, such as "Fred Smith"
    /// </summary>
    string FriendlyNameLabel { get; set; }

    /// <summary>
    /// returns all fields in the row as pipe delimited
    /// ex: 1,234.23|Fred Smith|[email protected]|
    /// </summary>
    string RowAsString { get; set; }


    /// <summary>
    /// if this is an excel file comparison, this should return the name 
    /// of the worksheet from whence this data came
    /// </summary>
    string SourceWorksheetName { get; set; }


    /// <summary>
    /// if this is an excel file comparison, this should return the name 
    /// of the worksheet range from whence this data came
    /// </summary>
    string SourceRangeName { get; set; }

    /// <summary>
    /// this will be modified by the validation process
    /// </summary>
    bool bReported { get; set; }
}
}

I have read NUMEROUS articles/books/forum postings about Interfaces. This concept feels like a black hole to me...and i'm on a project where i have to implement this. Anybody have ANY idea how the heck you implement this? By the way--i'm a COMPLETE newbie programmer...less than 2 months experience...therefore please do not chastise me for my green-ness please.

Thanks in advance.

A: 

If you are using visual studio, just write "public class foo : IValidationRowSet". Then click on foo with left click, then shift+alt+f10, down, enter. That will generate a stub for interface implementation.

And don't name a class "MyInterface", that's confusing. It's an implementation of interface, not an interface itself. :)

Arnis L.
+3  A: 

Consider interfaces to be a prototype or a template for a puzzle to be filled in - think of them as white space and lines where to put the pieces. You will have to derive the interfaces into concrete classes - the pretty picture puzzle.

Let me save this and I'll put up an example.

interface IFoo
{
    bool DoFoo(int number);
}

class Foo : IFoo
{
    public bool DoFoo(int number) {
         return (number++ >= 0); 
    }
}

class Foo2 : IFoo
{
    public bool DoFoo(int number) {
         return (number-- >= 0); 
    }
}

Now that I have that, I can do stuff like this.

IFoo foo;

if (!value)
    foo = new Foo();
else
    foo = new Foo2();

bool value2 = foo.DoFoo(27);

Notice, I cannot do this with interfaces:

// WRONG
Foo2 foo2 = new Foo();

So that basically sums up what an interface does and how it works. What your job now is to implement those concrete implementations of the interface.

Daniel A. White
I guess he does know what is an interface. At least - theoretically. :)
Arnis L.
True, but he says its a "black hole"/
Daniel A. White
when i meant it's like a "black hole" was that before this posting, i had little understanding from what i read as to WHY on earth anybody would use this...furthermore the implementation on most of the online examples i saw were simple piddly little things that didn't help with more complex implementations. so sorry if my newness offends anybody here.
@yeahumok - we all were where you were at our point sometime. i hoped my example helps.
Daniel A. White
A: 

Hard to tell where your mind is stuck with interfaces.

Interfaces are an abstract concept. Not only literally but by nature in that abstract classes and interfaces cannot be instantiated. An interface is even more abstract than an abstract class in that it cannot contain any executable code. It sets up a contract between the consumer of an interface and the class that implements an interface.

Now, if you hear polymorphism and you start scratching your head, then interfaces will be a tough nut. Interfaces are one of the common ways to introduce polymorphism in your application. You can have many implementations of IValidationReporter and of IValidationRowSet. Since you abstracted their contracts, any code that can work with those abstractions will be able to remain unchanged, even in circumstances where you switch implementations of those contracts.

Your code implements one of the interfaces but not the other. Please also note that static constructs cannot be expressed in contracts (interfaces)

flq
I believe that it's not tough at all, just demands some practice. :)
Arnis L.
+1  A: 

As a new developer myself, I find the best way to think of an interface as a template that includes all the public information about a class (attributes, methods etc.) as a list of what needs to be created for the class implementing it to do the job that is needed for those methods etc.

Now there should be a slew of people who will explain this much better than me, and correct my mistakes and hopefully explain interfaces differently to the articles/books/postings in a way that you (and hopefully I) can understand :)

StuperUser
+2  A: 

You can imagine that interface is like a list of questions which your class must answer. That way, you can create many classes which will all answer those questions in a different way.

But to the guy that asks questions (which is a ValidationReporter) it will only be important to get the answers, not who will answer them.

a. You need to tell compiler that your class implements the interface

// my class implements the interface
public class MyValidationRowSet : IValidationRowSet

b. You need to implement each interface method. This means that you need to make sure that each method actually does something. In Visual Studio, you can get some aid by right-clicking the interface in the line above and selecting "Implement Interface" from the context menu. This will create method stubs (empty methods which you can the fill in).

public class MyValidationRowSet : IValidationRowSet
{
     public int FieldCount
     { 
         get
         {
             // return something
         }
     }

    // you will need to implement each method from your
    // interface in order to compile successfully
}

I can see from your code (public class MyInterface: IValidationRowSet) that you didn't implement any method - you left them all blank. Compiler will not let you run the program until it is sure that your methods are returning proper results.

c. That is basically it. Once you get past point a., compiler will not let you run the program until you have implemented all methods in that interface. When you're done, you can create a new instance of your class which can "give answers":

// create a new instance of your class
MyValidationRowSet instance = new MyValidationRowSet();
Groo
A: 

Not entirely sure what you're asking, but here's some observations:

public class MyInterface: IValidationRowSet { ... }

MyInterface is not a "smart" name for your class, because it is not an interface. It is an actual implementation of an interface. I suggest instead ValidationRowSetImpl, or MyRowSet, or similar.

Also, you have

IList<string> lst = new List<string>();

stuck in the middle of your interface implementation. It should be explicitly mentioned as "private", and for reasons of good organization, should be at the bottom of your class. All the methods from the interface should be together, in the same order as the interface. All the private date used should be below that.

abelenky
bottom OR top. But be consistent :)
flq
+1  A: 

As a guide for making progress, I suggest hard-coding all the methods to return dummy data, or throw a Not Implemented exception.

For example:

RowNumber // Always returns 1
RowAsString // return "FirstName,LastName,PhoneNumber"
MatchedRow  // throw exception
FriendlyNameLabel // return "MyFriendlyRow"
KeyFieldLabel// return "MyKeyField"
SourceWorksheetName // return "DefaultWorksheet"
SourceRangeName  // return "DefaultRange"
bReported // return true;
FieldCount // return 3 (to match the number of fields indicated in RowAsString
FieldData // simple switch/case: 0=>FirstName, 1=>lastName, 2=>PhoneNumber
ValidationMessage // return "Data not validated"

That should make your code compile... and maybe even run, then you can start debugging it to figure out how it is supposed to be used. Little-by-little, remove the "dummy" implementations and put in "real" code.

A side note: your initial block of code, "ScanAndSerialize" seems to have nothing to do with IValidationRowSet. Is there a connection I'm missing?

abelenky
I agree, this is a good way to get it running quickly.
Groo