昨天的问题,虽然各位同行给与的相关的见解,但是仍然没有实现其功能,
参见“http://community.csdn.net/Expert/topic/4809/4809507.xml?temp=.7278101”
现在接着昨天的问题,退一步进行技术求助,
一个类Product,实例化ProductObj他的属性分为两种:PID等固定的属性/E_Pice等动态的属性(必须采用属性访问,提供方法访问)
固定的属性按照常规的方式进行编写,使用的时候直接采用ProductObj.PID
public class Product
{
private int m_ID;
public int PID
{
set{this.m_ID = value;}
get { return this.m_ID; }
}
public string E_Property
{
set{....= value;}
get { return ....;}
}
}
但是动态的属性非常规设计,用户在访问的时候直接按照ProductObj.E_Price(本身类中并没有E_Price属性),也就是说如果检测E_Price是动态属性(带有E_开头的属性),直接采用E_Property的属性过程进行操作,不知道这样的设计是否能够实现,请同行们给与帮助,问题解决后,连同昨天的百分贴一同给分。
参见“http://community.csdn.net/Expert/topic/4809/4809507.xml?temp=.7278101”
现在接着昨天的问题,退一步进行技术求助,
一个类Product,实例化ProductObj他的属性分为两种:PID等固定的属性/E_Pice等动态的属性(必须采用属性访问,提供方法访问)
固定的属性按照常规的方式进行编写,使用的时候直接采用ProductObj.PID
public class Product
{
private int m_ID;
public int PID
{
set{this.m_ID = value;}
get { return this.m_ID; }
}
public string E_Property
{
set{....= value;}
get { return ....;}
}
}
但是动态的属性非常规设计,用户在访问的时候直接按照ProductObj.E_Price(本身类中并没有E_Price属性),也就是说如果检测E_Price是动态属性(带有E_开头的属性),直接采用E_Property的属性过程进行操作,不知道这样的设计是否能够实现,请同行们给与帮助,问题解决后,连同昨天的百分贴一同给分。
解决方案 »
- SqlConnection方法取变值 并赋值给变量
- 关于c#调用c++函数,函数参数结构体指针
- 使用字节流生成图元文件发生“GDI+ 中发生一般性错误”
- c#能不能定义string类型的枚举变量?
- toolstrip 控件
- WinForm中的TreeView取结点修改后的文本问题?
- C#如何在打开主界面的同时打开登陆界面
- 怎么将label控件和数据库绑定啊?
- 请问使用using Microsoft.Data、using Microsoft.Data.Odbc,我该引用那个程序集?
- 如何解决任意一点是否在由N个点组成的不规则区域内?
- 用“.net安装与部署”制作的安装包,怎样在安装过程中设置config文件?
- 大家帮我看看这一条语句有什么问题呢?为什么老是报错啊?
s.getType();
这样的语法是无法实现的。
你可以用索引器:ProductObj["Price"]动态的属性必须用反射访问……
分类是由用户自己维护的,每一个产品都是一张表,用户通过管理界面可以动态维护表结构
属性就是表中的某些字段
using System.IO;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.CodeDom.Compiler;
using Microsoft.CSharp;namespace WindowsApplication1
{
public class CSharpCodeCompiler
{
private ICodeCompiler _compiler;
private CompilerParameters _parameters;
private string _options;
private CompilerResults _complerResults;
private string _sourceName;
private string _complerErrors; private readonly string[] _reference =
{
"System.dll", "System.Data.dll", "System.Xml.dll",
"System.Drawing.dll", "System.Windows.Forms.dll",
}; public CSharpCodeCompiler()
{
_compiler = new CSharpCodeProvider().CreateCompiler();
_parameters = new CompilerParameters(_reference);
_options = String.Empty;
_complerResults = null;
_complerErrors = String.Empty;
_sourceName = String.Empty;
} public string CompilerOptions
{
set
{
_options = value;
}
get
{
return _options;
} } public CompilerResults CompilerResults
{
get
{
return _complerResults;
}
} public string CompilerErrors
{
get
{
return _complerErrors;
}
} private string GetCompilerErrorList(CompilerResults results)
{
if(_complerResults.Errors.Count == 0)
{
return String.Empty;
} StringBuilder sb = new StringBuilder();
foreach(System.CodeDom.Compiler.CompilerError error in _complerResults.Errors)
{
string line = String.Format("{0}({1}) Error {2}: {3}",
_sourceName, error.Line, error.ErrorNumber, error.ErrorText);
sb.Append(line);
sb.Append(Environment.NewLine);
}
_sourceName = String.Empty; return sb.ToString();
}
protected string Compile(ICodeCompiler compiler, string statements, string assemblyPath, bool executable)
{
_parameters.GenerateInMemory = false;
_parameters.GenerateExecutable = executable;
_parameters.OutputAssembly = assemblyPath; if(CompilerOptions.Length > 0)
{
_parameters.CompilerOptions = CompilerOptions;
} if(_sourceName == String.Empty)
{
_sourceName = assemblyPath;
} _complerResults = compiler.CompileAssemblyFromSource(_parameters, statements);
_complerErrors = GetCompilerErrorList(_complerResults);
if(_complerResults.Errors.Count > 0)
{
return null;
} return assemblyPath;
} public virtual string Compile(string statements, string assemblyPath, bool executable)
{
return Compile(_compiler, statements, assemblyPath, executable);
} public string CompileScriptFile(string sourceFile, string assemblyPath, bool executable)
{
string strStatements; using(StreamReader st = new StreamReader(sourceFile, System.Text.Encoding.Default))
{
strStatements = st.ReadToEnd();
}
_sourceName = sourceFile; return Compile(strStatements, assemblyPath, executable);
} protected Type Compile(ICodeCompiler compiler, string className, string statements)
{
_parameters.GenerateInMemory = true;
_parameters.GenerateExecutable = false;
_parameters.OutputAssembly = null; if(CompilerOptions.Length > 0)
{
_parameters.CompilerOptions = CompilerOptions;
} if(_sourceName == String.Empty)
{
_sourceName = className;
} _complerResults = compiler.CompileAssemblyFromSource(_parameters, statements);
_complerErrors = GetCompilerErrorList(_complerResults);
if(_complerResults.Errors.Count > 0)
{
return null;
} Assembly assembly = _complerResults.CompiledAssembly;
return assembly.GetType(className);
} public virtual Type Compile(string className, string statements)
{
return Compile(_compiler, className, statements);
} public Type CompileScriptFile(string className, string sourceFile)
{
string strStatements; using(StreamReader st = new StreamReader(sourceFile, System.Text.Encoding.Default))
{
strStatements = st.ReadToEnd();
}
_sourceName = sourceFile; return Compile(className, strStatements);
} public object Invoke(Type type, string methodName, object[] param)
{
object objInstance = Activator.CreateInstance(type); BindingFlags flag = BindingFlags.InvokeMethod;
return type.InvokeMember(methodName, flag, null, objInstance, param);
}
}
}
public class Test
{
private string testCode = ""1"";
public string GetString(){return testCode;}
}";
CSharpCodeCompiler comp = new CSharpCodeCompiler();
Type typ = comp.Compile("Test", statements);
object obj = comp.Invoke(typ, "GetString", null);动态编译一个类,返回一个type给你。然后你就可以用反射对这个type进行操作了。上面是调用了一个方法,返回一个字符串
尝试一下
为什么什么都没有输出?
昨天的帖子马上结贴
我调用了test类里面的GetString返回了一个字符串
object obj = comp.Invoke(typ, "GetString", null);
你看看这个obj的值是什么