获取属性类型并传递给泛型方法

本文关键字:泛型方法 属性 类型 获取 | 更新日期: 2023-09-27 18:06:21

工作在。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>(),类型参数被自动设置为属性的类型?这可行吗?还是说我现在拥有的已经够好了?

更新

另外,我很想知道采用这种方法是否有任何缺点。我将不得不做很多API调用,所以我想知道如果使用反射实际上会减慢这与原始代码相比,我在每个getter和setter显式调用适当的方法?

获取属性类型并传递给泛型方法

解决你的第一点,我不认为你会进一步减少get代码没有过度复杂化;对我来说,只要指定类型就行了。

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

关于性能,我要说的首先是:测试它。如果您发现它很慢,那么您可以尝试缓存查找属性操作。这段代码将把反射的field.getValue调用包装在一个Func<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();
    }