gpt4 book ai didi

c# - C#中使用类来描述数据

转载 作者:太空宇宙 更新时间:2023-11-03 13:44:18 25 4
gpt4 key购买 nike

我正在用 C# 编写一个支持插件的应用程序。每个插件都必须介绍自己,以便应用程序可以为其准备合适的环境。当前信息对象看起来更像这样:

class FilterInfo
{
public InputInfo[] inputs;
public OutputInfo[] outputs;
bool IsConfigurable;
bool IsPlayable;
string TypeName;
}

这个结构将来肯定会扩展(但是,我想不会太多,它可能会扩大一倍)。我目前正在考虑如何正确实现此类信息。

在 C++ 中,我会按以下方式进行(我会将类剥离到一个字段以使示例更具可读性):

class FilterInfo
{
private:
std::vector<const InputInfo> inputs;

public:
std::vector<const InputInfo> & GetInputs()
{
return inputs;
}

const std::vector<const InputInfo> & GetInputs() const
{
return inputs;
}
}

现在,插件将实例化一个 FilterInfo 类,填写其字段,然后根据请求返回 const FilterInfo,这样就没有人可以更改信息的内容(好吧,没有人应该)。

在 C# 中,我只能想象以下“安全”解决方案:

public interface IInputInfo
{
bool SomeData
{
get;
}
}

public class InputInfo : IInputInfo
{
private bool someData;

public bool SomeData
{
get
{
return someData;
}
set
{
someData = value;
}
}

public bool IInputInfo.SomeData
{
get
{
return someData;
}
}
}

public interface IFilterInfo
{
ReadOnlyCollection<IInputInfo> Inputs
{
get;
}
}

public class FilterInfo : IFilterInfo
{
private InputInfo[] inputs;

public InputInfo[] Inputs
{
get
{
return inputs;
}
set
{
inputs = value;
}
}

public ReadOnlyCollection<IInputInfo> IFilterInfo.Inputs
{
return inputs;
}
}

插件当然会返回 IFilterInfo 而不是 FilterInfo,这样数据是只读的(好的,我知道反射,问题是通知用户,不应更改数据)。然而,这个解决方案在我看来非常笨拙 - 特别是与我之前引用的紧凑版本相比。

另一种解决方案可能是仅使用 getter 创建 FilterInfo,但它需要以某种方式将数据传递给它,并且最终可能会得到一个带有大量参数的巨大构造函数。


编辑:另一种解决方案是创建一个结构并在每次请求期间返回其副本。但是,数组是通过引用复制的,因此我每次都必须手动复制它们。

另一个方法是在每次有人请求时从头开始构建 FilterInfo,例如。

public FilterInfo Info
{
get
{
return new FilterInfo()
{
IsConfigurable = true,
IsPlayable = false,
Inputs = new[]
{
new InputInfo()
{
// (...)
}
}
}
}
}

有什么优雅的方法可以解决这个问题吗?

最佳答案

我认为您第一次几乎就答对了:

  1. 可插入程序集中定义一个只允许读取的公共(public)IFilterInfo接口(interface)。
  2. 插件程序集FilterInfo 类中实现该接口(interface),其属性具有内部 setter 。
  3. 让方法根据请求返回 FilterInfo 类的新实例。惯例建议在每次构造新实例的情况下使用方法而不是属性。 (如果您坚持使用属性,您可以在构建实例后存储实例并通过属性返回它)

示例:

在可插入组件中:

public interface IFilterInfo {
bool IsPlayable { get; }
bool IsConfigurable { get; }
}

在插件程序集中:

internal class FilterInfo : IFilterInfo {
public bool IsPlayable { get; internal set; }
public bool IsConfigurable { get; internal set; }
}

public IFilterInfo GetFilterInfo() {
return new FilterInfo() { IsPlayable = true, IsConfigurable = false };
}

内部 setter 和只读接口(interface)应该足以确保属性不会在插件程序集之外被修改。

关于c# - C#中使用类来描述数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15894022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com