在类中创建对基元类型字段的引用

本文关键字:类型 字段 引用 创建 | 更新日期: 2023-09-27 18:32:19

我有几个类有一些原始字段,我想为它们创建一个通用包装器以访问它们的字段。这个包装器应该以某种方式包含对我的类字段的引用,以便我可以读取/写入这些字段的值。这个想法是为这些类创建一个通用的体系结构,这样我就不必为每个类编写代码。这些类具有包含数字的字段,该数字将用作访问字段的 ID。

这是一些示例代码,可能会阐明我的要求。最后我想要的是更改 Fancy1 类对象中某个字段的值,而无需访问对象本身,而是通过其包装器。

class Fancy1
{
    public double level1;
    public bool isEnable1;
    public double level2;
    public bool isEnable2;
    public double level3;
}

class Fancy2
{
    public double level4;
    public bool isEnable4;
    public double level6;
    public bool isEnable6;
    public double level7;
}
class FieldWrapper
{
    public int id { get; set; }
    public object level { get; set; }
    public object isEnabled { get; set; }
    public FieldWrapper(int id, object level, object isEnabled)
    {
        this.id = id;
        this.level = level;
        this.isEnabled = isEnabled;
    }
}
class FancyWrapper
{
    private Fancy scn;
    public FancyWrapper(Fancy scn)
    {
        if (!(scn is Fancy))
            throw new ArgumentException(scn.GetType().FullName + " is not a supported type!");
        this.scn = scn;
    }
    private Dictionary<int, FieldWrapper> fieldLut = new Dictionary<int, FieldWrapper>();
    private List<FieldWrapper> _fields { get { return fieldLut.Values.ToList(); } }
    public List<FieldWrapper> fields
    {
        get
        {
            if (_fields.Count == 0)
            {
                foreach (System.Reflection.FieldInfo fieldInfo in scn.GetType().GetFields())
                {
                    if (fieldInfo.FieldType == typeof(double))
                    {
                        int satId = getIdNr(fieldInfo.Name);
                        fieldLut.Add(satId, new FieldWrapper(satId, fieldInfo.GetValue(scn), true));
                    }
                }
                foreach (System.Reflection.FieldInfo fieldInfo in scn.GetType().GetFields())
                {
                    if (fieldInfo.FieldType == typeof(bool))
                    {
                        int satId = getIdNr(fieldInfo.Name);
                        fieldLut[satId].isEnabled = fieldInfo.GetValue(scn);
                    }
                }
            }
            return _fields;
        }
    }
    private int getIdNr(string name)
    {
        System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(name, @"'d+");
        return Int32.Parse(m.Value);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Fancy1 fancy = new Fancy1();
        fancy.level1 = 1;
        fancy.isEnable1 = true;
        fancy.level2 = 2;
        fancy.isEnable2 = false;
        fancy.level3 = 3;
        FancyWrapper wrapper = new FancyWrapper(fancy);
        wrapper.fields[2].level = 10;
        // fancy.level2 should somehow get the value I set via the wrapper
        Console.WriteLine(fancy.level2);
        Console.ReadLine();
    }
}

编辑:花哨的类不能改变,因为它们是界面的一部分!

在类中创建对基元类型字段的引用

根据您正在处理的花式类的数量,您可以为每个公开一个通用接口的适配器/外观类创建一个适配器/外观类。 例如:

class Fancy1
{
    public double level1;
    public bool isEnable1;
    public double level2;
    public bool isEnable2;
    public double level3;
}
public class FieldWrapper
{
    private Action<double> _levelSetter;
    private Func<double>   _levelGetter;
    private Action<bool>   _enableSetter;
    private Func<bool>     _enableGetter;
    public double level     { get { return _levelGetter();  } set { _levelSetter(value);  }}
    public bool   isEnabled { get { return _enableGetter(); } set { _enableSetter(value); }}
    internal FieldWrapper(Func<double> levelGetter, Action<double> levelSetter, Func<bool> enableGetter, Action<bool> enableSetter)
    {
        _levelGetter = levelGetter;
        _levelSetter = levelSetter;
        _enableGetter = enableGetter;
        _enableSetter = enableSetter;
    }
}
abstract class FancyWrapper
{
    public FieldWrapper[] Fields { get; protected set; }
}
class Fancy1Wrapper : FancyWrapper
{
    private Fancy1 _fancy1;
    public Fancy1Wrapper(Fancy1 fancy1)
    {
        _fancy1 = fancy1;
        this.Fields = new[] { new FieldWrapper(() => fancy1.level1, level => _fancy1.level1 = level, () => _fancy1.isEnable1, enable => _fancy1.isEnable1 = enable),
                              new FieldWrapper(() => fancy1.level2, level => _fancy1.level2 = level, () => _fancy1.isEnable2, enable => _fancy1.isEnable2 = enable), };
    }
}

或者你可以花5分钟学习数据结构。请考虑以下示例:

var levels = new Dictionary<int, bool>
{
    {1, true}, 
    {2, false}
};
if (levels[1])
{
    //will run, because level 1 is true
}
if (levels[2])
{
    //will not run, because level 2 is false
}
if (levels.ContainsKey(3) && levels[3])
{
    //will not run, because dictionary does not contain entry for key 3
}
levels.Add(3, false);
if (levels.ContainsKey(3) && levels[3])
{
    //will not run, because level 3 is false
}
levels[3] = true;
if (levels.ContainsKey(3) && levels[3])
{
    //will run, because level 3 is true
}

这似乎是你想要的,但实际上并非如此。在任何级别上都非常尴尬。更具体地说,指针通常相当"类似非 C#",并且必须知道这些数字会破坏一开始就拥有单独类的意义。

仔细想想你想要完成什么。如果您在将其转换为代码时遇到问题,我们随时为您提供帮助。:)