How to get real method name istead of .ctor? - stack-trace

Hi i have method getting the name of calling method:
public static string GetMethodName()
{
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();
return trace.GetFrame(1).GetMethod().Name;
}
And when I track my bugs and exceptions I always get method name .ctor
how to avoid that or at least get something like ClassName<.ctor> ?

How about:
StackTrace stackTrace = new StackTrace();
foreach(StackFrame sf in stackTrace.GetFrames())
{
if (!sf.GetMethod().Name.StartsWith(".")) // skip all the ".ctor" methods
{
return sf.GetMethod().DeclaringType.Name + "." + sf.GetMethod().Name;
}
}
return "??"; // What do you want here?
Using a string compare is a bit heavy-handed, but it works :)

Related

Raise.Event<Action<T[]>> : Cannot raise event with the provided arguments

When I run the unit test below, it fails and returns this message:
System.ArgumentException : Cannot raise event with the provided
arguments. Use Raise.Event<Action'1>(CWaveform[]) to raise this event.
[Test]
public void WaveformsReceived_FourWaveformsReceived_WaveformPlotsEqual4()
{
IWorkflowController oWorkflowControllerMock = Substitute.For<IWorkflowController>();
IEventAggregator oEventAggregatorMock = Substitute.For<IEventAggregator>();
CDataAcquisitionViewModel oDataAcquisitionViewModel = new CDataAcquisitionViewModel(oWorkflowControllerMock, oEventAggregatorMock);
CWaveform[] aoWaveforms = { };
oWorkflowControllerMock.WaveformsReceived += aoWForms => aoWaveforms = aoWForms;
int nNumberOfWaveforms = 4;
CWaveform[] aoFourWaveforms = Enumerable.Range(0, nNumberOfWaveforms).Select(_ => new CWaveform()).ToArray();
oWorkflowControllerMock.WaveformsReceived += Raise.Event<Action<CWaveform[]>>(aoFourWaveforms);
Assert.AreEqual(aoWaveforms.Length, oDataAcquisitionViewModel.Plots.Count());
}
Raise.Event does not seem to work for an Action whose parameter is an array of reference types. It does work for an array of value types. Is it possible to make it work for reference types?
Edit: The declared type for IWorkflowController.WaveformsReceived is event Action<CWaveform[]>
System.ArgumentException Cannot raise event with the provided
arguments. Use Raise.Event<EventHandler1>(Object, IList1) to raise
this event.
I was seeing a similar error, which brought me here. However it was down to how I was raising the event. I had forgotten to include the sender and was blindly trying to send the EventHandler.
Bad
+= Raise.Event<EventHandler<string>>"Something");
Good
+= Raise.Event<EventHandler<string>>(null, "Something");

Using a Beakerx Custom Magic

I've created a custom Magic command with the intention of generating a spark query programatically. Here's the relevant part of my class that implements the MagicCommandFunctionality:
MagicCommandOutcomeItem execute(MagicCommandExecutionParam magicCommandExecutionParam) {
// get the string that was entered:
String input = magicCommandExecutionParam.command.substring(MAGIC.length())
// use the input to generate a query
String generatedQuery = Interpreter.interpret(input)
MIMEContainer result = Text(generatedQuery);
return new MagicCommandOutput(MagicCommandOutcomeItem.Status.OK, result.getData().toString());
}
This works splendidly. It returns the command that I generated. (As text)
My question is -- how do I coerce the notebook into evaluating that value in the cell? My guess is that a SimpleEvaluationObject and TryResult are involved, but I can't find any examples of their use
Rather than creating the MagicCommandOutput I probably want the Kernel to create one for me. I see that the KernelMagicCommand has an execute method that would do that. Anyone have any ideas?
Okay, I found one way to do it. Here's my solution:
You can ask the current kernelManager for the kernel you're interested in,
then call PythonEntryPoint.evaluate. It seems to do the job!
#Override
MagicCommandOutcomeItem execute(MagicCommandExecutionParam magicCommandExecutionParam) {
String input = magicCommandExecutionParam.command.substring(MAGIC.length() + 1)
// this is the Scala code I want to evaluate:
String codeToExecute = <your code here>
KernelFunctionality kernel = KernelManager.get()
PythonEntryPoint pep = kernel.getPythonEntryPoint(SCALA_KERNEL)
pep.evaluate(codeToExecute)
pep.getShellMsg()
List<Message> messages = new ArrayList<>()
//until there are messages on iopub channel available collect them into response
while (true) {
String iopubMsg = pep.getIopubMsg()
if (iopubMsg == "null") break
try {
Message msg = parseMessage(iopubMsg) //(I didn't show this part)
messages.add(msg)
String commId = (String) msg.getContent().get("comm_id")
if (commId != null) {
kernel.addCommIdManagerMapping(commId, SCALA_KERNEL)
}
} catch (IOException e) {
log.error("There was an error: ${e.getMessage()}")
return new MagicKernelResponse(MagicCommandOutcomeItem.Status.ERROR, messages)
}
}
return new MagicKernelResponse(MagicCommandOutcomeItem.Status.OK, messages)
}

AspectJ - Retrieve list of annotated parameters

From the following previous question (AspectJ - Presence of annotation in join point expression not recognized),
My goal:
In an aspect, i'd like to be able to extract/retrieve all annotated parameters from matching functions, no matter how many there are. (and then apply some treatment on but it's not the scope of this question)
So for the moment, this is what i did (not working):
#Before("execution (* org.xx.xx.xx..*.*(#org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
Object[] myArgs = jp.getArgs();
getLogger().info("Here: arg length=" + myArgs.length);
// Roll on join point arguments
for (Object myParam : myArgs) {
getLogger().info(
"In argument with " + myParam.getClass().getAnnotations().length
+ " declaread annotations");
getLogger().info("Class name is " + myParam.getClass().getName());
// Get only the one matching the expected #Standardized annotation
if (myParam.getClass().getAnnotation(Standardized.class) != null) {
getLogger().info("Found parameter annotated with #Standardized");
standardizeData(myParam.getClass().getAnnotation(Standardized.class), myParam);
}
}
}
This is the code matched by the advice:
public boolean insertLog(#Standardized(type = StandardizedData.CLIPON) CliponStat theStat) {
// ...
}
And the traces generated by a junit test:
INFO: ICI: arg lenght=1
INFO: In argument with 0 declaread annotations
Looks like it doesn't detect the annotation
So my question is: how to detect parameters which have specific annotation(s) ?
Does somebody have an idea how to do it?
Thanks in advance for your help.
Regards.
Edit: i found this thread Pointcut matching methods with annotated parameters, discussing of the same thing, and applied the given solution but it doesn't work..
I hope I understand you right.
myParam.getClass().getAnnotations() gives you the annotations on a class. Something like:
#Standardized(type = StandardizedData.CLIPON)
public class Main{...}
Maybe this pointcut/advice helps you:
#Before("execution (* org.xx.xx.xx..*.*(#org.xx.xx.xx.xx.xx.Standardized (*),..))")
public void standardize(JoinPoint jp) throws Throwable {
Object[] args = jp.getArgs();
MethodSignature ms = (MethodSignature) jp.getSignature();
Method m = ms.getMethod();
Annotation[][] parameterAnnotations = m.getParameterAnnotations();
for (int i = 0; i < parameterAnnotations.length; i++) {
Annotation[] annotations = parameterAnnotations[i];
System.out.println("I am checking parameter: " + args[i]);
for (Annotation annotation : annotations) {
System.out.println(annotation);
if (annotation.annotationType() == Standardized.class) {
System.out.println("we have a Standardized Parameter with type = "
+ ((Standardized) annotation).type());
}
}
}
}
This gives me the following output:
I am checking parameter: main.CliponStat#331f2ee1
#annotation.Standardized(type=CLIPON)
we have a Standardized Parameter with type = CLIPON

DataSet does not support System.Nullable<>

i have an app which has btn to preview report made in crystal report. I added Dataset as datasource of the report and dragged datatable from the toolbox and added the fields I need as columns. I got the instruction from this link http://aspalliance.com/2049_Use_LINQ_to_Retrieve_Data_for_Your_Crystal_Reports.2. This is my 2nd report the first one works and did not encounter any prob at all that is why i am confused, not to mention it also has nullable column. the error says: DataSet does not support System.Nullable<>.
private void ShowReportView()
{
string reportFile = "JudgeInfoFMReport.rpt";
ObservableCollection<tblJudgeFileMaint> judgeFileMaintList;
judgeFileMaintList = GenerateReport();
if (judgeFileMaintList.Count > 0)
{
CrystalReportViewerUC crview2 = new CrystalReportViewerUC();
crview2.SetReportPathFile(reportFile, judgeFileMaintList);
crview2.ShowDialog();
}
else
{
System.Windows.MessageBox.Show("No record found.", module, MessageBoxButton.OK, MessageBoxImage.Information);
}
}
private ObservableCollection<tblJudgeFileMaint> GenerateReport()
{
var result = FileMaintenanceBusiness.Instance.GetAllJudgeInfoList();
return new ObservableCollection<tblJudgeFileMaint>(result);
}
The error is in the part where I set datasource report.SetDataSource
public bool SetReportPathFile(string reportPathFile, IEnumerable enumerable)
{
string reportFolder = #"\CrystalReportViewer\Reports\";
string filename = System.Windows.Forms.Application.StartupPath + reportFolder + reportPathFile; // "\\Reports\\CrystalReports\\DateWiseEmployeeInfoReport.rpt";
ReportPathFile = filename;
report.Load(ReportPathFile);
report.SetDataSource(enumerable);
report.SetDatabaseLogon("sa", "admin007");
bRet = true;
}
_IsLoaded = bRet;
return bRet;
}
I read some answers and says I should set the null value to DBNUll which I did in the properties window of each column if it is nullable. Can anyone help me please? thanks
Your question can be seen in this post, but in a generic way ... that way you can pass an Object to a DataSet typed!
.NET - Convert Generic Collection to DataTable
figured it out. by using a collectionextention, copied somewhere, I forgot the link. Os to whoever it is who made the class, credits to you.
class method looks like this.
public statis class CollectionExtension {
public static DataSet ToDataSet<T>(this IEnumerable<T> collection, string dataTableName)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
if (string.IsNullOrEmpty(dataTableName))
{
throw new ArgumentNullException("dataTableName");
}
DataSet data = new DataSet("NewDataSet");
data.Tables.Add(FillDataTable(dataTableName, collection));
return data;
}
}
then you can use it by doing this in getting your source to your report:
private DataSet GenerateNeutralContEducReport(string dsName)
{
var contEduHistoryList = FileMaintenanceBusiness.Instance.GetManyNeutralFMContEducHistoryInfobyKeyword(CurrentNeutralFM.NeutralID, "NeutralID").ToList();
return CollectionExtensions.ToDataSet<tblContinuingEducationHistory>(contEduHistoryList, dsName);
}
I found little help from the other proposed answers but this solution worked.
A different way to solve this problem is to make the data column nullable.
DataColumn column = new DataColumn("column", Type.GetType("System.Int32"));
column.AllowDBNull = true;
dataTable.Columns.Add(column);
https://learn.microsoft.com/en-us/dotnet/api/system.data.datacolumn.allowdbnull?view=netcore-3.1
foreach (PropertyDescriptor property in properties)
{
dt.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
}

IronRuby performance issue while using Variables

Here is code of very simple expression evaluator using IronRuby
public class BasicRubyExpressionEvaluator
{
ScriptEngine engine;
ScriptScope scope;
public Exception LastException
{
get; set;
}
private static readonly Dictionary<string, ScriptSource> parserCache = new Dictionary<string, ScriptSource>();
public BasicRubyExpressionEvaluator()
{
engine = Ruby.CreateEngine();
scope = engine.CreateScope();
}
public object Evaluate(string expression, DataRow context)
{
ScriptSource source;
parserCache.TryGetValue(expression, out source);
if (source == null)
{
source = engine.CreateScriptSourceFromString(expression, SourceCodeKind.SingleStatement);
parserCache.Add(expression, source);
}
var result = source.Execute(scope);
return result;
}
public void SetVariable(string variableName, object value)
{
scope.SetVariable(variableName, value);
}
}
and here is problem.
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.SetVariable("a", 10);
evaluator.SetVariable("b", 1 );
evaluator.Evaluate("a+b+2", null);
vs
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.Evaluate("10+1+2", null);
First Is 25 times slower than second. Any suggestions? String.Replace is not a solution for me.
I do not think the performance you are seeing is due to variable setting; the first execution of IronRuby in a program is always going to be slower than the second, regardless of what you're doing, since most of the compiler isn't loaded in until code is actually run (for startup performance reasons). Please try that example again, maybe running each version of your code in a loop, and you'll see the performance is roughly equivalent; the variable-version does have some overhead of method-dispatch to get the variables, but that should be negligible if you run it enough.
Also, in your hosting code, how come you are holding onto ScriptScopes in a dictionary? I would hold onto CompiledCode (result of engine.CreateScriptSourceFromString(...).Compile()) instead -- as that will help a lot more in repeat runs.
you can of course first build the string something like
evaluator.Evaluate(string.format("a={0}; b={1}; a + b + 2", 10, 1))
Or you can make it a method
if instead of your script you return a method then you should be able to use it like a regular C# Func object.
var script = #"
def self.addition(a, b)
a + b + 2
end
"
engine.ExecuteScript(script);
var = func = scope.GetVariable<Func<object,object,object>>("addition");
func(10,1)
This is probably not a working snippet but it shows the general idea.