Ugniusst
Ugniusst

Reputation: 1

C# Can i implement interface with IEnumerable object and struct?

So I want to write an interface, which should be able to be implemented with any data. This is interface i wrote till now. The reason I chose IEnumerable is because I need to give class Computer or struct Processor

 public interface IData<T> where T : IEnumerable<object>
{
    public T ReadData();
    public void WriteData(T list);
}

And I have two different datas, one is Computer, which is a class. And the other one is Processor (struct)

public struct Processor
{
    public string Name { get; set; }
    public string AmazonLink { get; set; }
    public  string AmazonBin { get; set; }

    public Processor(string name, string link)
    {
        Name = name;
        try
        {
            //constructor parses elements which is needed to generate AmazonURL in URLGenerator project

            AmazonLink = link.Substring(0, link.IndexOf("&dc"));
            string binStart = link.Substring(link.IndexOf("bin%") + 4);
            AmazonBin = "%7C" + binStart.Substring(2);
        }
        catch (Exception e)
        {

            throw new InnerCustomException("Erorr occured while trying to substring the link", e);
        }
    }

I tried to do that like this, but it seems like I am not allowed to do that because of boxing?

public class ProcessorServiceCSV : IData<IEnumerable<Processor>>
{   private string Path { get; set; }
    private FileMode Filemode { get; set; }
    public ProcessorServiceCSV(string path, FileMode fileMode)
    {
        Path = path;
        Filemode = fileMode;
    }
    //reads Processor list from CSV file
    public IEnumerable<Processor> ReadData()
    {
        try
        {
            using (var reader = new StreamReader(Path))
            using (var csv = new CsvReader(reader))
            {
                csv.Configuration.CultureInfo = CultureInfo.InvariantCulture;
                csv.Configuration.Delimiter = ",";
                csv.Configuration.RegisterClassMap<ProcessorMap>();
                var records = csv.GetRecords<Processor>().ToList();

                return records.ToList();
            }
        }
        catch (FileNotFoundException)
        {
            throw new DataCustomException("File not found", this);
        }
        catch (Exception e)
        {
            throw new DataCustomException("Something's wrong happened:" + e.Message, this);
        }
    } public void WriteData(IEnumerable<Processor> processors)
    {
        try
        {
            using (var stream = File.Open(Path, Filemode))
            using (StreamWriter sw = new StreamWriter(stream))
            using (CsvWriter cw = new CsvWriter(sw))
            {
                foreach (Processor processor in processors)
                {
                    cw.Configuration.RegisterClassMap<ProcessorMap>();
                    cw.WriteRecord<Processor>(processor);
                    cw.NextRecord();
                }
            }
        }
        catch (FileNotFoundException)
        {
            throw new DataCustomException("File not found", this);
        }
        catch (FileLoadException)
        {
            throw new DataCustomException("File could not be opened", this);
        }
        catch (Exception e)
        {
            throw new DataCustomException("Something's wrong happened:" + e.Message, this);
        }
    }
}

}

I know I could change Processor from struct to class, but is it possible to keep struct? Thank you in advance

Upvotes: 0

Views: 589

Answers (2)

John Alexiou
John Alexiou

Reputation: 29244

Is this the basic skeleton code of what you are trying to do? Note that the generic collection is IEnumerable<T> and not IEnumetable<object> and hence I updated your IData<T> definition

public class Computer
{
}

public struct Processor
{
}

public interface IData<T> 
{
    IEnumerable<T> ReadData();
    void WriteData(IEnumerable<T> list);
}


public class ComputerData : IData<Computer>
{
    public IEnumerable<Computer> ReadData()
    {
        throw new NotImplementedException();
    }

    public void WriteData(IEnumerable<Computer> list)
    {
        throw new NotImplementedException();
    }
}
public class ProcessorData : IData<Processor>
{
    public IEnumerable<Processor> ReadData()
    {
        throw new NotImplementedException();
    }

    public void WriteData(IEnumerable<Processor> list)
    {
        throw new NotImplementedException();
    }
}

Please indicate if this code meets your requirements, and if not why.

Upvotes: 0

ps2goat
ps2goat

Reputation: 8475

You have a lot of other problems, including not giving us a complete, working bit of code.

However, it looks like you should be able to do what you want to do if you use an Interface for the Processor struct instead of the actual struct type.

Also, notice how I changed the type for T in your classes. You don't need IEnumerable in your T constraint. I did delete some of your code to get it to somewhat work (the exception in the struct constructor, e.g.), so you will need to do some more work here.

public interface IData<T>
{
     IEnumerable<T> ReadData();
     void WriteData(IEnumerable<T> list);
}

public interface IProcessor {
    string Name { get; set; }
    string AmazonLink { get; set; }
    string AmazonBin { get; set; }
}

public struct Processor : IProcessor
{
    public string Name { get; set; }
    public string AmazonLink { get; set; }
    public  string AmazonBin { get; set; }

    public Processor(string name, string link)
    {
        Name = name;
            //constructor parses elements which is needed to generate AmazonURL in URLGenerator project

            AmazonLink = link.Substring(0, link.IndexOf("&dc"));
            string binStart = link.Substring(link.IndexOf("bin%") + 4);
            AmazonBin = "%7C" + binStart.Substring(2);
    }
}

public class ProcessorServiceCSV<T> : IData<T> where T: IProcessor
{   private string Path { get; set; }
    private FileMode Filemode { get; set; }
    public ProcessorServiceCSV(string path, FileMode fileMode)
    {
        Path = path;
        Filemode = fileMode;
    }
    //reads Processor list from CSV file
    public IEnumerable<T> ReadData()
    {
        try
        {
            using (var reader = new StreamReader(Path))
            using (var csv = new CsvReader(reader))
            {
                csv.Configuration.CultureInfo = CultureInfo.InvariantCulture;
                csv.Configuration.Delimiter = ",";
                csv.Configuration.RegisterClassMap<ProcessorMap>();
                var records = csv.GetRecords<Processor>().ToList();

                return records.ToList();
            }
        }
        catch (FileNotFoundException)
        {
            throw new DataCustomException("File not found", this);
        }
        catch (Exception e)
        {
            throw new DataCustomException("Something's wrong happened:" + e.Message, this);
        }
    }
    }

Upvotes: 1

Related Questions