简体   繁体   中英

Parser for multiple data types without returning object

I'm building a parser for some data that's given as XML, something similar to:

Get file in path %windir%\\system32\\calc.exe and retrieve it's CreationTime

The small problem that I have is that the type of object that I'm retrieving ( FileInfo in example above) and the data type of the property I'm reading ( CreationTime which is DateTime in example above) isn't always the same.

For example: on a FileInfo object alone I could be asked for:

  • bool Exists
  • DateTime CreationTime
  • DateTime LastWriteTime
  • long Size
  • Version Version

Other object types could be things like FolderInfo , RegistryKey and RegistryValue

With that in mind, I created the following code:

public interface IPropertyRetriever<out T>
{
    public string Name { get; }

    public Property Property { get; }

    public T RetrieveProperty();
}

public enum Property
{
    Count,
    DateCreated,
    DateModified,
    RegistryKeyExists,
    RegistryValueExists,
    Size,
    Value,
    Version
}

public class FilePropertyRetriever<T> : IPropertyRetriever<T>
{
    public FilePropertyRetriever(string name, Property property, string path, bool is64Bit)
    {
        Name = name;
        Property = property;
        Path = path;
        Is64Bit = is64Bit;
    }

    public string Name { get; }

    public Property Property { get; }

    public string Path { get; }

    public T RetrieveProperty()
    {
        var file = ...
        // Do something to retrieve FileInfo, 
        // assumes if it got to code below FileInfo.Exists is true

        return (T) (object) (Property switch
        {
            Property.Count => file.Exists,
            Property.DateCreated => file.CreationTime,
            Property.DateModified => file.LastWriteTime,
            Property.Size => file.Length,
            Property.Version => Version.TryParse(FileVersionInfo.GetVersionInfo(Path).ProductVersion,
                out var version)
                ? version
                : null
        });
    }
}

I know that my T RetrieverProperty() method isn't exactly very good programming - I'm telling my method what type I want it to return when in fact it knows already and using generics to cast to the correct type (and boxing it first if DateTime / long / int ), but I really can't think of a better way of doing this.

Any suggestions on how to improve this?

PS: The reason why the RetrieveProperty() accepts no parameters and instead uses properties is because the device where the object is created and where the method are run is not the same, the object is serialised and sent over.

why can't IPropertyRetriever just be this:

public interface IPropertyRetriever
{
    public string Name { get; }

    public int Count {get;}
    public DateTime DateCreated {get;}
    public DateTime DateModified {get;}
    public bool RegistryKeyExists {get;}
    public bool RegistryValueExists {get;}
    public long Size {get;}
    //etc    
}

And call it something different IFileInformation. Or have different interfaces returned for different objects with a base interface as not all the above properties are relevant to all objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM