【问题标题】:C# Create Class by Concatenating StringC#通过连接字符串创建类
【发布时间】:2020-01-23 04:22:08
【问题描述】:
public class Customer
{
    public int ProductId { get; set;},
    public string ProductName { get; set;},
    public string ProductDescription { get; set;},
    public float SalesAmount { get; set;}
}

public class Tracker<T>
{
    [Required, ValidateObject]
    public T Body { get; set; }
    public Date date { get; set; }
    public string GUID{ get; set; }
}

有没有办法通过句点或连接字符串自动创建一个类,它将在 Visual Studio 中自动编译

public class CustomerTracker : Tracker<Customer>
{
}

因此,我可以选择任何类,而不是像上面那样创建 100 个类,它会自动生成这个类。是否有任何 C# 库函数允许这样做?

所以Customer.Tracker = public class CustomerTracker : Tracker&lt;Customer&gt;
Customer.ListTracker = public class CustomerTracker : Tracker&lt;IEnumerable&lt;Customer&gt;&gt;

Food.Tracker = public class FoodTracker : Tracker&lt;Food&gt;

【问题讨论】:

  • 创建类是什么意思?你还没有创建类,你刚刚声明了类。 New() 或 Activator.CreateInstance() 创建一个类的实例..你能准确地说你想要什么,它不是很清楚......
  • 嗨@Frenchy 我希望能够通过编写这个 Customer.Tracker 来动态创建类,并让 C# 编译器自动知道它的含义,而不是遍历我们的 1000 个类并手动声明类,
  • 最好描述一下你要解决的问题。
  • 您对反射所做的任何事情都需要将代码加载到运行时中,因此编译器将无法自动知道它的含义。代码模板系统可能对您更有用。所以基本上他们会根据你的简短表格为你生成类文件。然后可以在您的项目中使用它,编译器将了解这些类。查看链接:docs.microsoft.com/en-us/dotnet/framework/…
  • 嗨@mtkachenko,我们必须声明 1000 个用跟踪器包装类的类,而不是手动创建 1000 个类,我希望有一个以自己的方式可读的包装函数跨度>

标签: c# asp.net-core dynamic reflection .net-core


【解决方案1】:

如果您想动态创建编码并动态编译,您可以像在我的数学程序中那样,动态添加一些函数而无需重新编译项目..

我有带有程序主体的文本文件:

using System;

// file curve.txt
namespace UserFunction
{                
    public class BinaryFunction
    {
        public static double MyFunction(double x, double param)
        {
            return param == 0 ?  MyFunction0(x, 0.3) : MyFunction1(x);
        }

        private static double MyFunction0(double x, double param)
        {
            return (1 - param) * x + param * (Math.Pow(x, 3));
        }
        private static double MyFunction1(double x)
        {
            return x * 2;
        }
    }
};

在项目 C# 中,我动态编译程序并创建 dll。在我可以从创建的 dll 中调用该方法之后。

            // in project C#
    private Func<double, double, double> betterFunction;

    private MethodInfo CreateAndCompileFunction(string filename)
    {
        FileInfo fi = new FileInfo(@".\folder\CurveAssembly.dll");
        CSharpCodeProvider provider = new CSharpCodeProvider();
        CompilerParameters compilerparams = new CompilerParameters();
        compilerparams.OutputAssembly = @".\folder\CurveAssembly.dll";
        CompilerResults results = provider.CompileAssemblyFromFile(compilerparams, filename);

        if (results.Errors.Count > 0)
        {
            // Display compilation errors.
            Console.WriteLine("Errors building {0} into {1}",
                fi.FullName, results.PathToAssembly);
            foreach (CompilerError ce in results.Errors)
            {
                Console.WriteLine("  {0}", ce.ToString());
            }
        }
        else
        {
            // Display a successful compilation message.
            Console.WriteLine("Source {0} built into {1} successfully.",
                fi.FullName, results.PathToAssembly);
        }

        Type binaryFunction = results.CompiledAssembly.GetType("UserFunction.BinaryFunction");
        return binaryFunction.GetMethod("MyFunction");
    }
    public void compileFunction(string curvename)
    {
        MethodInfo function = CreateAndCompileFunction(@".\folder\curve.txt");
        betterFunction = (Func<double, double, double>)Delegate.CreateDelegate(typeof(Func<double, double, double>), function);
    }


    //calling the method inside the dll (betterfunction)
    public double MyFunction(double x, double param)
    {
        return betterFunction(x, param);
    }

【讨论】:

  • 嗨 Frenchy,谢谢,我将不得不研究如何用于上述课程,感谢它
  • T4 模板有点类似于这个功能。取决于它可能值得调查:docs.microsoft.com/en-us/visualstudio/modeling/…
  • 给出了分数并接受了答案,也请随意竖起大拇指,谢谢
【解决方案2】:

看起来您需要许多没有实现的响应类才能使您的公共 API 变得更好。 IE。而不是返回BaseResponse&lt;SomeClass&gt;,你想返回SomeClassResponse : BaseResponse&lt;SomeClass&gt;。如果是这样,我建议使用T4 templates。使用 T4 你可以像这样编写模板逻辑:

  1. YourApp.Domain命名空间获取所有类
  2. 为每个域类生成响应类,如public sealed SomeClassresponse : BaseResponse&lt;SomeClass&gt; {}
  3. 只需在您的代码中使用这些类,因为它们在编译时是已知的。

您不需要在运行时生成类,因为您已经知道需要生成的所有类。无论如何,运行时生成会比 T4 生成慢。

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2017-06-24
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    相关资源
    最近更新 更多