I got a CS0426 compiler error when trying to open an Excel using SpreadsheetDocument class from DocumentFormat.OpenXml.Packaging namespace.
I realized that this was because I was using new and, for some reason, the compiler didn't like it.
Why can't I create an instance of the object using new?
//Error CS0426
using (SpreadsheetDocument goldenFile = new SpreadsheetDocument.Open(goldenPath, true));
//Ok code
using (SpreadsheetDocument goldenFile = SpreadsheetDocument.Open(goldenPath, true));
Judging by its name and context, the SpreadsheetDocument.Open method opens a new spreadsheet file for you to read/write from/to.
This should be the correct way to use this API:
using (SpreadsheetDocument goldenFile = SpreadsheetDocument.Open(goldenPath, true)) {
...
}
You need to understand that not every class needs to be created by you writing the word new and directly calling the constructor. Sometimes, in this case for example, the instance of SpreadsheetDocument is probably created somewhere inside the Open method. The Open method simply returns the new instance, so that you can assign it to a variable (goldenFile in this case).
You can write a class that gets created with a static method too:
class Foo {
// properties...
// private constructor
private Foo() { ... }
public static GiveMeAFoo() {
return new Foo();
}
}
I can now create an instance of Foo without directly using new:
var foo = Foo.GiveMeAFoo();
Something similar is happening inside Open.
The compiler gives off the error CS0426 because it thinks like this:
I see that you are using the new operator, so you are creating a new instance of a type. What type is it that you are creating? Let's see... It's SpreadsheetDocument.Open! But wait a minute! That's not a type! I can't find a type called Open in SpreadsheetDocument!
Hence the error:
The type name 'Open' does not exist in the type 'SpreadsheetDocument'.
It's not working because as is, when you're using new you essentially telling your code - "Create an object of a nested class 'Open'".
Either get rid of new or implement public constructor, and then call static Open method.
The Open method is a static method which uses new in its implementation and returns an instance of SpreadsheetDocument. This is why you don't need to use new. Refer to documentation.
Related
In the DotNetYaml sample code I'm looking at, there's a C# construct:
var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention());
var order = deserializer.Deserialize<Order>(input);
What is the equivalent F# code? I've tried
let deserializer = new Deserializer(namingConvention=new CamelCaseNamingConvention())
deserializer.Deserialize<Meta>(input)
If you have a C# library that defines optional parameters, then you can use the syntax you are using in your question. To quickly show that's the case, I compiled the following C# code as a library:
using System;
namespace Demo {
public class MyClass {
public static void Foo(int first, string second = "foo", string third = "bar") { }
}
}
You can reference this and use it from F# as follows:
open Demo
MyClass.Foo(1, third="hi")
I tried to do this with YamlDotNet which, I guess, is the library that you were using, but I get an error that the Deserializer class does not have namingConvention as an argument, so my guess would be that you are probably using a different version of the library than you are thinking (or perhaps, my guess of what library you're using was wrong...).
I want to populate this type of using statement through Roslyn.
Using(var logger = new MethodLogger("someparam"))
{
}
How can I generate it..
I am trying this SyntaxFactory.UsingStatement
For stuff like this I use roslynquoter. It generates roslyn calls out of C# code. For your case it returns something like this:
SyntaxFactory
.UsingStatement(SyntaxFactory.Block()/* the code inside the using block */)
.WithDeclaration(SyntaxFactory
.VariableDeclaration(SyntaxFactory.IdentifierName("var"))
.WithVariables(SyntaxFactory.SingletonSeparatedList(SyntaxFactory
.VariableDeclarator(SyntaxFactory.Identifier("logger"))
.WithInitializer(SyntaxFactory.EqualsValueClause(SyntaxFactory
.ObjectCreationExpression(SyntaxFactory.IdentifierName(#"MethodLogger"))
.WithArgumentList(/* arguments for MethodLogger ctor */)))
I have a WPF project. I create an entity model. When I create an instance from that model.
I press "." after it to use extension methods like "select , where ,..."
That methods didn't appear after the instance
I found the following methods
this is the code :
GazEntity Context = new GazEntity();
private ObservableCollection<GasPapers> _papers;
public RegisterPaper()
{
this.InitializeComponent();
// here is the problem
Context.GasPapers .
// I didn't see any extension methods after period
}
}
You need a using for System.Linq. So add the following line at the top of the code file:
using System.Linq;
I'm using Visual Studio 2013 to create a Visual C# Windows Forms Application and I'm not using the Designer to setup the form.
I'm trying to use a Dictionary to store Bitmaps so that I can call them later by name. But when I debug the script I get the error:
An unhandled exception of type 'System.NullReferenceException' occurred in SimpleForm.exe
Additional information: Object reference not set to an instance of an object.
From the line:
width = imgLetters["a"].Width;
Any help would be greatly appreciated.
Cut down version of code which still produces the error:
using System;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace SimpleForm
{
public class Test : Form
{
static Bitmap bmpLetterA;
static Bitmap bmpLetterB;
static Bitmap bmpLetterC;
private Dictionary<string, Bitmap> imgLetters;
public Test()
{
ImgInitialize();
ImgWidth();
}
private void ImgInitialize()
{
Dictionary<string, Bitmap> imgLetters;
bmpLetterA = new Bitmap("a.png");
bmpLetterB = new Bitmap("b.png");
bmpLetterC = new Bitmap("c.png");
imgLetters = new Dictionary<string, Bitmap>();
imgLetters.Add("a", bmpLetterA);
imgLetters.Add("b", bmpLetterB);
imgLetters.Add("c", bmpLetterC);
}
private void ImgWidth()
{
int width = 0;
width = imgLetters["a"].Width;
}
}
}
Remove the line Dictionary<string, Bitmap> imgLetters; from ImgInitialize. This creates a local variable with the same name as the member variable. It is then filled, but never used, while the member variable remains uninitialized.
Tipps for avoiding problems like this:
You could name instance members in a special way to make clear the variable is an instance member (for example m_member instead of member).
You could prefix access to an instance member with this. to make clear which variable you want to access.
You could try to avoid naming local variables the same as instance members.
The problems lies here:
private void ImgInitialize()
{
Dictionary<string, Bitmap> imgLetters;
This variable shadows the class's field private Dictionary<string, Bitmap> imgLetters;. Remove this declaration from the method ImgInitialize and it'll work fine.
Friendly tip to prevent such mistakes in the future: when using a class member, append this:
this.imgLetters = new Dictionary<string, Bitmap>();
this.imgLetters.Add("a", bmpLetterA);
this.imgLetters.Add("b", bmpLetterB);
this.imgLetters.Add("c", bmpLetterC);
This way, even if you have local variable with the same name it won't interfere.
The problem is in your ImgInitialize() method.
remove this Line
Dictionary<string, Bitmap> imgLetters;
What you are doing is creating a local variable with the same name as your global variable. So it is this one that you are adding values to. This then lost when the method has completed due to its scope.
Your global variable is still null at this point and this is why the error occurs.
I have to migrate a vb6 program to C# .net 3.5
the user starts SAP logon and authenticates,
then he can use the tool to fetch and insert the data using the tool
the problem:
i can create a new GuiApplication with reflection, but i can't fetch currently opened GuiSessions with it :/
here is the vb6 part of the code that gets currently opened GuiApplication with all opened GuiSessions
Dim obj As Object
Set obj = CreateObject("SAPGUI")
Set obj = obj.GetScriptingEngine
If TypeName(obj) = "GuiApplication" Then
Set SapAutomationObject = obj
SapAutomationObject.AllowSystemMessages = False
Debug.Print "SAP Automation OK"
End If
i tried it with reflection:
GuiApplication Application = (GuiApplication)System.Activator.CreateInstance(Type.GetTypeFromProgID("SapGui.ScriptingCtrl.1"));
i got an instance but no existing sessions
public static void testConnection()
{
SapROTWr.CSapROTWrapper sapROTWrapper = new SapROTWr.CSapROTWrapper();
object SapGuilRot = sapROTWrapper.GetROTEntry("SAPGUI");
object engine = SapGuilRot.GetType().InvokeMember("GetSCriptingEngine", System.Reflection.BindingFlags.InvokeMethod,
null, SapGuilRot, null);
SAPconnection.sapGuiApp = engine as GuiApplication;
GuiConnection connection = sapGuiApp.Connections.ElementAt(0) as GuiConnection;
GuiSession session = connection.Children.ElementAt(0) as GuiSession;
MessageBox.Show(session.Info.User + " !!||!! " + session.Info.Transaction);
}
Use This method, you have to reference SapROTWr.DLL which is in the sapgui folder of your SAP installation.
This works for me (SAP 730 / Win7):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SAPFEWSELib;
using SapROTWr;
namespace FIT.SapHelper
{
public static class stcSapHelper
{
public static void testConnection()
{
SapROTWr.CSapROTWrapper sapROTWrapper = new SapROTWr.CSapROTWrapper();
object SapGuilRot = sapROTWrapper.GetROTEntry("SAPGUI");
object engine = SapGuilRot.GetType().InvokeMember("GetScriptingEngine", System.Reflection.BindingFlags.InvokeMethod, null, SapGuilRot, null);
GuiConnection connection = (engine as GuiApplication).OpenConnection("BOX DESCRIPTION");
GuiSession session = connection.Children.ElementAt(0) as GuiSession;
}
}
}
Assuming that SAPGUI is a COM object then you should be able to take a reference to it and create it as a new object without using reflection. i.e. Use early binding and not late binding even though the original VB6 code is using 'late binding'
Secondly, assuming late binding, shouldn't the Type.GetTypeFromProgID("SapGui.ScriptingCtrl.1") fragment be Type.GetTypeFromProgID("SapGui") to match the original VB6? you might need to check on the object model for SAPGUI to make sure you're referencing the right object.
the only solution that i found to work with running sessions is to load that code in a dll and access it via c#
SAP released SAP .NET connector to provide standartized way to interact with SAP system from within of .NET application. Look at http://service.sap.com/connectors, you must be SAP partner to be able access to the page