昨天的问题,虽然各位同行给与的相关的见解,但是仍然没有实现其功能,
参见“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的属性过程进行操作,不知道这样的设计是否能够实现,请同行们给与帮助,问题解决后,连同昨天的百分贴一同给分。

解决方案 »

  1.   

    朋友可以考虑使用多态和继承,把基本固定的属性放在父类中,动态的属性放在子类中,然后可以根据类型来访问其中不同的属性,获取类型:String s="";
    s.getType();
      

  2.   

    ProductObj.E_Price
    这样的语法是无法实现的。
    你可以用索引器:ProductObj["Price"]动态的属性必须用反射访问……
      

  3.   

    to kssys() :
    分类是由用户自己维护的,每一个产品都是一张表,用户通过管理界面可以动态维护表结构
    属性就是表中的某些字段
      

  4.   

    using System;
    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);
    }
    }
    }
      

  5.   

    string statements = @"using System;

    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进行操作了。上面是调用了一个方法,返回一个字符串
      

  6.   

    to lookatliu(独孤常败):
    尝试一下
      

  7.   

    to lookatliu:
    为什么什么都没有输出?
    昨天的帖子马上结贴
      

  8.   

    你要输出什么啊?
    我调用了test类里面的GetString返回了一个字符串
    object obj = comp.Invoke(typ, "GetString", null);
    你看看这个obj的值是什么