c# – 为int,float等类型分配其他属性以供反射
我试图自动化我的变量的显示(通过反射收集),这些变量位于Unity的特定脚本中.问题是分配自定义值(例如:“string DisplayName”,“bool DisplayMe”,“bool WriteMe”等).当谈到我的自定义类时,我理解我将如何做,但我想避免为此目的重新构建float,string,int等类型.
例如,假设我有: public class myBaseClass { public string Name = "Display Name"; public bool AmReadable = true; public bool AmWritable = true; } 然后: public class myDoubleFloat: myBaseClass { public float ValueFirst; public float ValueSecond; } 所以在Unity的一些脚本中我定义它: public class SomeScriptOnGameObject : MonoBehaviour { public myDoubleFloat myFirstVariable{get; set;} public float mySecondVariable{get; set;} } 所以稍后用反射我可以检查是否应该读取“myFirstVariable”,它的显示名称等等 – 而对于“mySecondVariable”我不能执行此检查.如何在不重新发明轮子的情况下为每个类型创建一个类,如float,int,List等? 解决方法
包装值对象(int,float等)可能不是最好的方法.除了额外的复杂性(以及错误的可能性),你现在正在膨胀游戏的内存占用.
(我在这些例子中故意避免使用更新的C#语法) 由于您已经处于反射上下文中,而不是包装您的值对象,我建议使用基于属性的方法.例如: public class SomeScriptOnGameObject { [DisplayName("First Variable"),Writable] public float FirstVariable { get; set; } [DisplayName("Second Variable")] public float SecondVariable { get; set; } [DisplayName("Some Field")] public float Field; public float FieldWithNoAttributes; } 这样做的好处是可以在元数据中保留字段的元数据,而不是在您创建的每个实例中携带所有内容的副本. 实际属性也很容易创建.我将从最简单的一个开始,WritableAttribute: [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class WritableAttribute : Attribute { } 这个空类是将字段或属性标记为“可写”所需的全部内容. AttributeUsage将此标记为仅对字段和属性有效(例如,不是类). 另一个属性DisplayName只是稍微复杂一些: [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class DisplayNameAttribute : Attribute { public string DisplayName { get; private set; } public DisplayNameAttribute(string displayName) { DisplayName = displayName; } } 主要区别在于具有displayName参数的构造函数和DisplayName属性.这会强制编译器期望该属性的参数. 使用一些扩展方法,您可以使事情变得非常干净: public static class AttributeExtensions { public static bool IsWritable(this MemberInfo memberInfo) { return memberInfo.GetCustomAttributes(typeof(WritableAttribute)).Any(); } public static string DisplayName(this MemberInfo memberInfo) { var displayNameAttribute = memberInfo.GetCustomAttributes(typeof(DisplayNameAttribute)) .FirstOrDefault() as DisplayNameAttribute; return displayNameAttribute == null ? null : displayNameAttribute.DisplayName; } public static PropertyInfo Property<T>(this T _,string propertyName) { return typeof(T).GetProperty(propertyName); } public static FieldInfo Field<T>(this T _,string fieldName) { return typeof(T).GetField(fieldName); } } (既然你提到你已经在使用反射,那么你可能不需要最后两种方法.) 最后,一个简单的XUnit测试来演示: public class UnitTest1 { [Fact] public void Test1() { var obj = new SomeScriptOnGameObject(); Assert.True(obj.Property("FirstVariable").IsWritable()); Assert.False(obj.Property("SecondVariable").IsWritable()); Assert.False(obj.Field("Field").IsWritable()); Assert.Equal("First Variable",obj.Property("FirstVariable").DisplayName()); Assert.Equal("Second Variable",obj.Property("SecondVariable").DisplayName()); Assert.Equal("Some Field",obj.Field("Field").DisplayName()); Assert.Null(obj.Field("FieldWithNoAttributes").DisplayName()); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Cocos2d-x结构学习(十六)CCLayerColor、CCProgressTimer、
- [Swift]LeetCode485. 最大连续1的个数 | Max Consecutive O
- Cairngorm + BlazeDS 整合 Flex + Java 的 Demo (实例)
- Oracle 12c 数据库备份与恢复
- ios – Crashlytics Mac app如何运作?
- Pytest 学习(二十四)- @allure.severity 标记用例级别的使
- c# – 扩展方法中的表达式树将在本地进行评估
- c# – Rhino模拟一个抽象类,没有模拟它的虚方法?
- react-native – React Native Image组件,需要未知模块
- React study (三)事件函数