Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不返回对象的多数据类型解析器_C#_.net_Parsing - Fatal编程技术网

C# 不返回对象的多数据类型解析器

C# 不返回对象的多数据类型解析器,c#,.net,parsing,C#,.net,Parsing,我正在为一些以XML形式给出的数据构建一个解析器,类似于: 在路径%windir%\system32\calc.exe中获取文件并检索其CreationTime 我遇到的一个小问题是,我正在检索的对象类型(FileInfo,在上面的示例中)和我正在读取的属性的数据类型(CreationTime,在上面的示例中是DateTime)并不总是相同的 例如:仅在FileInfo对象上,我可能会被要求: bool存在 DateTime CreationTime DateTime LastWriteTim

我正在为一些以XML形式给出的数据构建一个解析器,类似于:

在路径
%windir%\system32\calc.exe中获取文件
并检索其
CreationTime

我遇到的一个小问题是,我正在检索的对象类型(
FileInfo
,在上面的示例中)和我正在读取的属性的数据类型(
CreationTime
,在上面的示例中是
DateTime
)并不总是相同的

例如:仅在
FileInfo
对象上,我可能会被要求:

  • bool存在
  • DateTime CreationTime
  • DateTime LastWriteTime
  • 长码
  • 版本版本
其他对象类型可以是
FolderInfo
RegistryKey
RegistryValue

考虑到这一点,我创建了以下代码:

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
        });
    }
}
公共接口IPropertyRetriever
{
公共字符串名称{get;}
公共属性属性{get;}
公共T RetrieveProperty();
}
公共枚举属性
{
计数
创建日期,
日期修改,
注册表项存在,
注册价值存在,
大小,
价值
版本
}
公共类FilePropertyRetriever:IPropertyRetriever
{
PublicFilePropertyRetriever(字符串名称、属性、字符串路径、bool为64位)
{
名称=名称;
财产=财产;
路径=路径;
IS64位=IS64位;
}
公共字符串名称{get;}
公共属性属性{get;}
公共字符串路径{get;}
公共T RetrieveProperty()
{
var文件=。。。
//做一些事情来检索文件信息,
//假设它在FileInfo.Exists下面的代码为true
返回(T)(对象)(属性开关
{
Property.Count=>file.Exists,
Property.DateCreated=>file.CreationTime,
Property.DateModified=>file.LastWriteTime,
Property.Size=>file.Length,
Property.Version=>Version.TryParse(FileVersionInfo.GetVersionInfo(Path).ProductVersion,
输出变量(版本)
版本
:null
});
}
}
我知道我的
T RetrieverProperty()
方法并不是很好的编程——我告诉我的方法我希望它返回什么类型,而实际上它已经知道了,并使用泛型强制转换为正确的类型(如果
DateTime
/
long
/
int
,则首先装箱),但我真的想不出比这更好的方法了

对如何改进这一点有什么建议吗


PS:
RetrieveProperty()
不接受参数,而是使用属性的原因是,创建对象和运行方法的设备不同,对象被序列化并发送过来。

为什么IPropertyRetrier不能是这样的:

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    
}

称之为不同的信息。或者使用基本接口为不同的对象返回不同的接口,因为并非所有上述属性都与所有对象相关。

为什么不能将数据反序列化到一个在属性枚举中具有这些属性的类中?如果调用方知道它想要的属性,那么它可以使用适当的property@TimRutter调用方是本地的,而不是远程的。服务器序列化类,将其发送到客户端。客户机对其进行反序列化,根据给定数据检索属性,并对其进行处理。了解数据类型而不是处理
对象
很重要。当我只对一个属性感兴趣时,我想检索每一个可能的属性并将其加载到类中,这是错误的经济性。因为并非所有对象都有
DateCreated
Version
Size
(等等)。因为我对一个属性感兴趣,感觉就像是把每一个可能的属性加载到一个类中,当我已经知道我想要的是哪一个时,只使用一个。。。不必要。以上是一个接口而不是类,因此您根本不必加载所有数据。请看我的第二条评论,您返回不同的接口,这取决于您反序列化的内容。您有句话要说“//做点什么来检索文件信息,”您不只是在那里加载所有内容吗?第三,你有一个属性枚举,这意味着你可以很容易地要求一个没有大小的对象的大小,所以我不认为你的解决方案比我上面得到的更好。我认为你把这件事想得太多了,这也意味着每个属性都可以为空,例如。。。至于在没有大小的对象上请求大小,您可以从上面我抛出的代码中看到,如果该对象不支持该属性。