C# Using CodeDom to add variables as part of a class - c#

I am attempting to create the following code through the use of CodeDom:
public partial class mainClass
{
public byte[] bytes = null;
}
I have no problem creating the class, and I found ways to declare variables through the use of CodeDom using the CodeVariableDeclarationStatement method, but I am unsure of how to add a variable declaration as part of my class.
Here is what I have tried thus far:
CodeTypeDeclaration mainClass = new CodeTypeDeclaration("mainClass");
mainClass.IsPartial = true;
mainClass.IsClass = true;
mainClass.Attributes = MemberAttributes.Public;
Namespaces.Types.Add(mainClass);
CodeVariableDeclarationStatement variableDeclaration = new(CodeVariableDeclarationStatement(typeof(byte[]), "bytes", new CodePrimitiveExpression("String.Empty");
I am open to any suggestions and ideas. Thank you for any help,
Evan.

Try to use this
CodeMemberField field = new CodeMemberField(typeof(byte[]), "bytes");
field.Attributes = MemberAttributes.Public;
mainClass.Members.Add(field);

Related

c# Cannot create InlineKeyboardButton

I am creating a telegram bot, but I am unable to create any InlineKeyboardButton objects.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telegram.Bot.Types.InlineKeyboardButtons;
namespace BuildAutomation.Controllers
{
public class Test
{
public TestMethod()
{
var none = new InlineKeyboardButton("No", "build|no");
var yes = "Yes";
var betaControl = new InlineKeyboardButton(yes, "build|betacontrol");
var betaNode = new InlineKeyboardButton(yes, "build|betanode");
var betaBoth = new InlineKeyboardButton(yes, "build|betaboth");
InlineKeyboardMarkup menu;
menu = new InlineKeyboardMarkup(new[] { betaBoth, none });
}
}
}
I keep getting the error 'Cannot create an instance of the abstract class or interface 'InlineKeyboardButton'. I realize that InlineKeyboardButton is an abstract class, but i see many examples creating an object of InlineKeyboardButton.
Did I miss something?
example 1
example 2
example 3
Instantiation of InlineKeyboardButton directly was correct in previous versions.
There is a new commit for about one month ago which indicates that InlineKeyboardButton is made abstract from then on. You must use derived classes instead. InlineKeyboardUrlButton, InlineKeyboardPayButton and etc. are all derived from InlineKeyboardButton.
It seems that the examples' repository is not updated yet.
Check this link for more details about the mentioned commit:
https://github.com/TelegramBots/telegram.bot/commit/ddaa8b74e3ab5eab632dbe2e8916c2fe87b114a3
Use InlineKeyboardCallbackButton Example, InlineKeyboardCallbackButton("Yes", "CallBackData") instead of InlineKeyboardButton("Yes", "CallbackData")
You couldn't create a new instance of abstraction class. So use sample bellow
var KeyboardButons = new InlineKeyboardButton[][]
{
new InlineKeyboardButton[]
{
InlineKeyboardButton.WithCallbackData("سفارش", callbackQueryData) ,
InlineKeyboardButton.WithCallbackData("بازگشت", "return")
}
};
var replyMarkup = new InlineKeyboardMarkup()
{
InlineKeyboard = KeyboardButons
};

DLR: Do i really need code generation here?

spent some time again with the scripting interface of my app.
i guess i now have an advanced dlr problem here.
I have a python script
I have an .NET object [o1]
I call a method on the python script from .NET via Iron Python.
The python code creates an object [o2]
The python code calls an method on object [o1] passing [o2] as an argument (Via subclassing DynamicMetaObject)
In the .NET code of the o1-method i want to dynamically call methods on o2
For example i could do that via
((dynamic)o2).FuncInPythonScript
so far so good thats all working.
.NET calls Python (step 3)
Python calls back .NET (step 5)
So i have a basic biderectional control flow between .NET and Python.
We go further:
In the [o1]-method I use LanguageContext.GetMemberNames on [o2]
I wanna call these members somehow via reflection or expressions.
Meaning i dont wanna use the dynamic keyword as in step 7.
Instead somehow call the methods via reflection.
Problem is:
a) I do not know how to get the RuntimeType of the Python-Type, meaning i have no System.Reflection.MethodInfo so i stuck here
b) I try to use LanguageContext.CreateCallBinder and MetaObject.BindInvokeMember so i should have the method 'FuncInPythonScript' bound
But then i'm stuck in how to finally call the bound method.
I see i could use code generation to just generate the code as in step 7, just with the member names from step 8.
But is that really necessary?
I do not see wether approach a) or b) might work or maybe there is somthing i did not think of.
Please do not answer with basic "How do i invoke a python method from .NET" hints.
That is done in steps 1-7 and i have no problem doing this. It's really an advanced problem.
namespace DynamicMetaObjectTest
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Dynamic;
using System.Linq.Expressions;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Hosting.Providers;
class Program
{
internal sealed class CDotNetObject : IDynamicMetaObjectProvider
{
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression aExp)
{
return new CInvoker(this, aExp);
}
private sealed class CInvoker : DynamicMetaObject
{
internal CInvoker(CDotNetObject aGws, Expression aExp) : base(aExp, BindingRestrictions.Empty, aGws)
{
this.DotNetObject = aGws;
}
private readonly CDotNetObject DotNetObject;
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
{
var aMethodInfo = this.GetType().GetMethod("GetSetResultDelegate");
var aExp = Expression.Call(Expression.Constant(this), aMethodInfo);
var aRestrictions = BindingRestrictions.GetTypeRestriction(this.Expression, this.LimitType);
var aMetaObject = new DynamicMetaObject(aExp, aRestrictions);
return aMetaObject;
}
public Action<object> GetSetResultDelegate()
{
return this.DotNetObject.SetResultProvider;
}
}
public void SetResultProvider(object aPythonObject_O2)
{
var aResult = ((dynamic)aPythonObject_O2).GetResult(); // this is for noobs. ;-)
var aMetaObjectProvider = (IDynamicMetaObjectProvider)aPythonObject_O2;
var aMetaObject = aMetaObjectProvider.GetMetaObject(Expression.Constant(aPythonObject_O2));
var aLanguageContext = HostingHelpers.GetLanguageContext(gScriptEngine);
var aMemberNames = aLanguageContext.GetMemberNames(aPythonObject_O2);
var aNonSystemMembers = from aMemberName in aMemberNames where !aMemberName.StartsWith("__") select aMemberName;
foreach (var aMemberName in aNonSystemMembers)
{
Console.WriteLine("Getting function result from Python script: " + aMemberName);
// Now problem:
// P1) How to determine wether its an function or an member variable?
// P2) How to invoke the method respectively get the value of the member variable?
// Your turn ;-)
// some of my failures:
{ // does not work:
//var aVar1Binder = aLanguageContext.CreateGetMemberBinder("GetVar1", false);
//var aVar1Bound = aMetaObject.BindGetMember(aVar1Binder);
//var aCallInfo = new CallInfo(0 , new string[]{});
//var aInvokeBinder = aLanguageContext.CreateCallBinder("GetVar1", false, aCallInfo);
//var aInvokeBound = aMetaObject.BindInvokeMember(aInvokeBinder, new DynamicMetaObject[]{ aVar1Bound});
////var aInvokeExp = Expression.Invoke(Expression.Constant(aInvokeBound), new Expression[] { });
}
{ // does not work
//var aExpandable = (IronPython.Runtime.Binding.IPythonExpandable)aMetaObject;
}
}
}
}
static ScriptEngine gScriptEngine;
static void Main(string[] args)
{
var aScriptRuntime = IronPython.Hosting.Python.CreateRuntime();
// That's the python script from step 1:
var aCode = "class CustomView(object) :" + Environment.NewLine +
"\tdef GetResult(self) :" + Environment.NewLine +
"\t\treturn 42;" + Environment.NewLine + // cuz 42 is the answer to everything ;-)
"DotNetObject.SetResultProvider(CustomView())";
var aEngine = aScriptRuntime.GetEngine("py");
gScriptEngine = aEngine;
var aScope = aEngine.CreateScope();
var aDotNetObject = new CDotNetObject();
aScope.SetVariable("DotNetObject", aDotNetObject);
// That's the invoke to pything from step 3:
aEngine.Execute(aCode, aScope);
}
}
}

How to fix ambiguous reference errors?

I have a web app that allows importing of contacts from Hotmail, Yahoo and GMail. I finally have it almost completed but since I added the importing of GMail, I am getting ambiguous reference errors and I am unsure how to fix them without breaking any code.
Here is a screen shot of the errors:
Try to use unique class names as much as possible. This will be the better solution in the end.
Write the entire namespace when referencing
OAuth.OAuthBase a = new ...;
Google.GData.Client.OAuthBase b = new ...;
Make an using alias for one or both:
using n2 = OAuth;
using Google.GData.Client;
n2.OAuthBase a = new ...; // referenced using namespace
OAuthBase b = new ...; // referenced through existing `using`
you can try something like this..
using GoogleOAuthBase = Google.GData.Client.OAuthBase;
namespace abc
{
public class Program
{
//make sure this Google.GData.Client.OAuthBase is instansiateable
var googleBase = new GoogleOAuthBase();
}
}
you can try entire name space as well.
var googleBase = new Google.GData.Client.OAuthBase();

Windows Form Application using Codedom C#

I am trying to produce a Windows Application Form via Codedom. I found a great example showing me how to do this for a Console Application but I can't seem to make this work for a Windows Form.
Here is what I have so far:
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string Output = "Out.exe";
Button ButtonObject = (Button)sender;
textBox2.Text = "";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, textBox1.Text);
Textbox1.text Contains the following:
Public Class Form1: Form
{
}
I'm really not sure what else to put... I am very new to this stuff and I can't seem to understand the articles I came across.
If you're new to CodeDom I strongly suggest you to use Linq2CodeDom which allows you to write your code in expressions which later will be translated through CodeDom into VB or C# code. With this library you can write something like this:
public void Generate()
{
var c = new CodeDomGenerator();
c.AddNamespace("Samples")
.AddClass("Form1")
.AddMethod(MemberAttributes.Public | MemberAttributes.Static, ()=>"YourMethodName", Emit.stmt(() => MessageBox.Show("Method Body")));
}
Assuming that you are actually able to create the EXE at the moment (as you are missing some using statements in your Form1 declaration) I would start by adding the entry point, the static Main method that creates and displays a new Form1 instance:
using System;
using System.Windows.Forms;
public class Form1 : Form
{
public static void Main(string[] args)
{
var form1 = new Form1();
Application.Run(form1);
}
}
That should at least get a window appearing when you run your generated EXE. #soandos also has a good point, you should be able to copy and paste from the source created when you create a form in Visual Studio, althought you should remember that VS2008+ uses partial classes so you need to combine the contents of Form1.cs and Form1.Designer.cs.

What's the difference between Marshal.GenerateGuidForType(Type) and Type.GUID?

Type classType = typeof(SomeClass);
bool equal = Marshal.GenerateGuidForType(classType) == classType.GUID;
I haven't found a case that fail this condition.
So why and when should I use the Marshal method instead of simply getting the GUID property?
see http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.generateguidfortype.aspx
... GenerateGuidForType provides the same functionality as the Type.GUID property.
So according to documentation they are the same. However, Marshal.GenerateGuidForType works only for RuntimeType objects, while Type.GUID is provided for some other Type implementations as well.
E.g.:
using System;
using System.CodeDom;
using System.Runtime.InteropServices;
using System.Workflow.ComponentModel.Compiler;
namespace Samples
{
class Program
{
static CodeCompileUnit BuildHelloWorldGraph()
{
var compileUnit = new CodeCompileUnit();
var samples = new CodeNamespace("Samples");
compileUnit.Namespaces.Add(samples);
var class1 = new CodeTypeDeclaration("Class1");
samples.Types.Add(class1);
return compileUnit;
}
static void Main(string[] args)
{
var unit = BuildHelloWorldGraph();
var typeProvider = new TypeProvider(null);
typeProvider.AddCodeCompileUnit(unit);
var t = typeProvider.GetType("Samples.Class1");
Console.WriteLine(t.GUID); // prints GUID for design time type instance.
Console.WriteLine(Marshal.GenerateGuidForType(t)); // throws ArgumentException.
}
}
}
According to MSDN, "GenerateGuidForType provides the same functionality as the Type.GUID property". It should be safe to use the one that suits you the best.

Categories

Resources