0

在 .Net 4.5 中工作。

我正在制作封装 ActiveX 控件(具体是 CadCorp SIS activeX 控件)的类,并且基本上将一些内部可用的对象复制到该控件(但不是外部)。从外部,内部对象的属性必须使用接受文本字符串的 API 进行操作。

在每个类中,我最终都会编写用于通过 API 获取和设置值的属性,并且我一遍又一遍地使用基本相同的代码,例如Control.GetInt(TargetDescripor, TargetIdentifier, PropertyName);,因此我试图使用泛型将代码减少到最低限度。我现在有这样的方法:

public T GetPropertyValue<T>(ObjectTypes Target, string PropertyName, int TargetIdentifier = 0)

它标识正确的 API 方法并返回所需的值。

我仍然必须使用正确的描述符和正确的属性名称从每个对象调用此方法。我已经进一步减少了。例如,如果我在其中一个对象中获得属性,则使用以下代码:

public Class MyObject
{
    public bool MyObjectPropertyX
    {
        get { return this.GetProperty<bool>(); }
    }

    private const string _MyObjectPropertyX = "APICommandString";

    private T GetPropertyValue<T>([CallerMemberName] string PropertyName = null)
    {
        string apiCommand = (string)this.GetType().GetField("_" + PropertyName, BindingFlags.NonPublic | BindingFlags.Static).GetValue(this);

        // Call the method which executes the API command with the correct object
        // descriptor and get the value
    }
}

这很好用。

现在我想知道是否可以在属性的 getter 中调用this.GetProperty<T>()type 参数自动设置为属性的类型?这可行吗?还是我现在拥有的和它一样好?

更新

另外,我很想知道转向这种方法是否有任何缺点。我将不得不进行很多 API 调用,所以我想知道与我在每个 getter 和 setter 中显式调用适当方法的原始代码相比,使用反射是否真的会减慢速度?

4

1 回答 1

1

为了解决您的第一点,我认为您不会在get不使事情过于复杂的情况下进一步减少代码;只是指定类型对我来说似乎很好。

如果您希望能够在不对字符串进行硬编码的情况下确定属性名称,则可以将此方法与反射一起使用。

关于性能,我首先要说的是:测试它。如果您发现它很慢,那么您可以尝试缓存您查找的属性操作。此代码会将反射field.getValue调用包装在 aFunc<string>中,以便每次都不需要反射查找。请记住,反射 api 无论如何都会在内部进行一些缓存,因此这可能没有什么好处。

    private readonly IDictionary<String, Func<String>> _cache = new Dictionary<String, Func<String>>();

    private String GetApiCommand(String propertyName)
    {
        Func<String> command;
        if (_cache.TryGetValue(propertyName, out command))
        {
            return command();
        }

        var field = GetType().GetField("_" + propertyName, BindingFlags.NonPublic | BindingFlags.Static);//.GetValue(this);

        if (field != null)
        {
            Func<String> action = () => (String)field.GetValue(this);
            _cache[propertyName] = action;

            return action();
        }

        throw new NotSupportedException();
    }
于 2013-03-28T10:45:29.003 回答