编译时设计基于模型的系统

我有一个模型类很少的系统,每个类都有另一个成员,但所有模型的行为都是相同的-

例如,所有模型都是来自用户的请求输入格式为: Hi, Please enter {MemberName} value as {MemberType}:并将输入转换为 MemberType。

因为这打算成为库,所以我希望在每个模型中我都可以在编译时访问他的成员(或类似成员)myModel.get("memberName"),而不是 by ,而是 bymyModel.memberNamemyModel.get(modelEnum.MemberName)ormyModel.ListOfMember[0]或者也许Factory.getMember(myModel, SpecificModelMembersList[0])等等。

我不需要在运行时添加或删除成员,只需创建一个在编译时添加它们的好方法,而不是更改将成员添加到模型类的所有代码。

你会如何设计它?

我使用 C#。

谢谢你,你可以建议一个英文修复。


江户川乱折腾
浏览 151回答 1
1回答

MYYA

我的想法是使用 lambda 表达式以简单直观的方式访问属性信息数据(使用 IntelliSense 支持和所有可用的重构)。演示该方法的代码如下。using System;using System.Linq.Expressions;using System.Reflection;namespace ConsoleAppTest2{&nbsp; &nbsp; class Program&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; static void Main(string[] args)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var myModel = new MyModel();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var cmb = ConsoleModelBuilder<MyModel>.RequestFromComsole(myModel)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .FillProp(x=>x.MethodName)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .FillProp(x => x.Birthday);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Console.ReadLine();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; internal class MyModel&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public int MethodName { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public DateTime Birthday { get; set; }&nbsp; &nbsp; }&nbsp; &nbsp; internal class ConsoleModelBuilder<T>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public T Model { get; private set; }&nbsp; &nbsp; &nbsp; &nbsp; public static ConsoleModelBuilder<T> RequestFromComsole(T obj)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new ConsoleModelBuilder<T>() { Model = obj };&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public ConsoleModelBuilder<T> FillProp<TProperty>(Expression<Func<T, TProperty>> propertyLambda)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PropertyInfo info = GetPropertyInfo(Model, propertyLambda);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine($"Hi, Please enter {info.Name} value as {info.PropertyType.Name}:");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Code to parse console input and fill property of Model&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public PropertyInfo GetPropertyInfo<TSource, TProperty>(&nbsp; &nbsp; TSource source,&nbsp; &nbsp; Expression<Func<TSource, TProperty>> propertyLambda)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Type type = typeof(TSource);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MemberExpression member = propertyLambda.Body as MemberExpression;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (member == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ArgumentException(string.Format(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Expression '{0}' refers to a method, not a property.",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; propertyLambda.ToString()));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PropertyInfo propInfo = member.Member as PropertyInfo;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (propInfo == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ArgumentException(string.Format(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Expression '{0}' refers to a field, not a property.",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; propertyLambda.ToString()));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (type != propInfo.ReflectedType &&&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !type.IsSubclassOf(propInfo.ReflectedType))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ArgumentException(string.Format(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Expression '{0}' refers to a property that is not from type {1}.",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; propertyLambda.ToString(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return propInfo;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}访问 PropertyInfo 的核心方法来自 StackOverflow 问题Retrieving Property name from lambda expression。
打开App,查看更多内容
随时随地看视频慕课网APP