How can I access the Value of my CommandLineParser? - c#

There is something I don't understand with the NuGet package CommandLineParser. This is the first time I see this?
Let me show you first:
On the left in my Auto Watch frame I can see the Value property. But, on the right, in Immediate Window I cannot access it. How is this possible. How can I use this package and read my Value Path after Parsing?
result.Value
error CS1061: 'ParserResult<Options>' does not contain a definition for 'Value' and no accessible extension method 'Value' accepting a first argument of type 'ParserResult<Options>' could be found (are you missing a using directive or an assembly reference?)
What is this watch folder doing I'm not doing?

By digging into the source code, you can see that ParserResult<T> is an abstract class..
The WithParsed extension method does a check to see if the ParserResult is a concrete type of Parsed, invokes the delegate and returns it https://github.com/commandlineparser/commandline/blob/master/src/CommandLine/ParserResultExtensions.cs
So now you're working with the abstract base class instead of the implementation, that's why you can't just do result.Value as that property is not sitting on the base class but rather the implementation.
My guess is that the Auto watch can know the actual type and show you the entire object and the Immediate window can't.
To work with .Value, you can cast it to Parsed<Options>

The exact example of using this CommandLineParser is used in this project: https://www.dropbox.com/s/nhq9os8dd9fim9u/FloorplanTransformation-3D-Walls.rar?dl=0
This is a visual studio project, check that out you will get a better understanding.
By the way here is a brief explanation:
you will have to create an instance of the Parser class.
Parser parser = Parser.Default;
Then to parse the arguments do the following
PraserResult<object> parser_result = parser.ParseArguments<MeshGenerateOptions, MorphologicalTransformOptions, other options>(args)
Here we have classes MeshGenerateOptions and MorphologicalTransformOptions with Attribute [Verb]
Now do the following to invoke the corresponding callback functions for each parsed arguments
parserResult.WithParsed<MeshGenerateOptions>(VerbHandlers.HandleGenerateMesh);
parserResult.WithParsed<MorphologicalTransformOptions>(VerbHandlers.HandleMorphologicalTransform);
Here, VerbHandlers is a static class not of much interest, HandleGenerateMesh and HandleMorphologicalTransform are Callback functions that are invoked when the corresponding verb is parsed.
You get the demo of How to use the above project you can watch the tutorial: https://www.youtube.com/watch?v=MNILyflAxdY&t=21s But this is just for building and using the above project.

Related

Why do I get compiler error CS0117 - 'class name' does not contain a definition for 'method name'

I am trying to call a load_words() method from Words class in the Main() method and it's giving me this error:
Error CS0117 'Words' does not contain a definition for 'load_words'
How do I call this function?
-If you are using it in different namespace and trying to use the other namespace's dll then it wont refer this method.
-You may need to rebuild the project
-if not try create class with namespace name might resolve your problem
namespace.Words words = new namespace.Words();
words.load_words();
The compiler isn't telling you that it can't find the class, Words. It's telling you that it can't find the method.
Sometimes the method exists but you can't call it. For example, maybe it's not public. But if that were the case you would get a different error message.
So the most likely cause is a typo where you're calling the method. Verify you've got the name of the method exactly correct. It's case-sensitive. If you haven't exactly matched the name of the method then the method you're calling actually doesn't exist, which is why the compiler says the class doesn't contain that method.
Another possibility is that you've got two classes named Words. One is in the same namespace as your Main method and the other isn't. If the one with a load_words method is in another namespace, then the compiler is looking at the class that doesn't have that method.

Why can't I resolve implicitly?

I always right click to resolve the namespace implicitly.
But for some namespace, I cannot resolve it implicitly and have to resolve it explicitly, leading to code like program1.logging.ErrorLogger.ErrorArise. Why can't I resolve implicitly?
Check this fiddle:
https://dotnetfiddle.net/6Px9BQ
The problem is, there are two or more classes sharing the same name, so its not implicitly possible to know which you refer to, hence you need to specifiy the name explicit, by providing its full namespace name.
If you dont want to specify long qualifiers all the time, you can shorten them like this:
Apple.Berry.Cheese.Cake cake = new Apple.Berry.Cheese.Cake();
shortened:
using abc = Apple.Berry.Cheese;
abc.Cake cake = new abc.Cake();
Visual studio gives you a lot of power and can easily let you pass over some concepts. One of the tools provided is that you can right click to add a using directive at the top of the code file which signals the compiler what class names will mean at compile time.
But if two namespaces have the same class name, and both are in use in the same class, then you have to explicitly tell the compiler in each case what to use.

Type.GetType() visibility issue between projects (Visual C#)

I ran into a peculiarish problem. I am working on a dynamic factory project and my intention is to be able to create new objects based on an XML file. My problem is this:
I have a separate project for the base classes for the factory where I have
public abstract class DynamicContentFactory<T, Params> where T: class where Params: DynamicParameters
In this abstract class I have a static method Create as follows
public static T Create(Params data)
Params only includes one string as a default called Type. I want to limit the creation of objects to the same namespace as the base class T, so I do the following:
string namespaceStr = typeof(T).ToString();
namespaceStr = namespaceStr.Substring(0, namespaceStr.LastIndexOf('.') + 1);
Type type = Type.GetType(namespaceStr + data.Type);
In my main project, I have a specific factory class
public class ItemFactory : DynamicContent.DynamicContentFactory<ItemFactory, ItemParameters>
{
}
The problem is that when I call ItemFactory.Create, the Type.GetType returns null. ItemFactory resides in the same namespace as the Items I want it to create, but the base class resides in another. Is there any way around this?
I have tried changing the parameter of Type.GetType() to typeof(T).ToString() in order to test whether it can find it and it did not find it either. I can't create a link from my DynamicContent project to my main project because a link to the other way already exists. I feel it is silly that it cannot even find the type of the class it was initialized in.
So my question is: What would be the best way to go around this? I would prefer maintaining my DynamicContent project in a separate project as a separate library rather than having to include it in my main project. Is there a way to make it find the classes or do I have to create third project for the types I want to initialize with this in order to be able to reference it from both the main project and the DynamicContent project?
BR,
-Sami
Behavior you are observing is expected - Type.GetType
typeName - The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
Note that your current code works because it falls under "currently executing assembly" portion of the specified behavior where just namespace+name is enough.
You should specify full name of the type when requesting it, but you can check what namespace the type will use.
You can switch to Assembly.GetType instead of Type.GetType and use T's assembly to lookup types you want to create.
Alternative is to scan all loaded assemblies for type you want, but it may be not enough if the type is coming from not-yet-loaded assembly.
Remainder: namespace names in .Net don't mean much - they are convention to make code more readable, but there is no particular link between assembly and namespaces that are implemented in it.

CSharp: How do I dynamically call a class(with constructor) and it's methods?

I've been reading examples of Reflection for two days and I can't quite seem to piece together everything to fit what I need. In fact I thought I was using reflection, until I noticed my "using System.Reflection" was grayed out. :-)
I have an xml file that contains my class names and the methods contained within. The order of the methods or even the names can change. Once I read them in I want to be able to execute them. Seems simple enough.
I have the following test code:
// myClassName = "namespace.TransactionServices"
Type tb = Type.GetType(myClassName);
// Classes will always have the same constructor
object classInstance = Activator.CreateInstance (
tb,
new object[]
{
authorization.apiKey,
authorization.userName,
testData.servicesEndPoint
});
//Grab the method I want
//myMethodName = "GetVersion"
MethodInfo mymethod = tb.GetMethod(myMethodName);
// no parameters for this method call
object result = mymethod.Invoke(classInstance, null);
tb is null. I was just going to work away at trying to get the correct API for creating the class, but I don't even know if the rest of what I have is valid.
Any suggestions?
Thanks
Edit: Added namespace. Activator.CreateInstance is returning error that constructor is not found.. It is there.
The class name must be fully qualified (including namespace and, most likely, the assembly) in order for it to be resolved. If you know the class is in your current executing assembly, you can use Assembly.GetExecutingAssembly().GetType()
Are you sure you specified the complete class name including namespace? without the namespace, the result will be null.
For GetType you have to provide a fully qualified name. You can get it for an existing object using
MyObject.GetType().AssemblyQualifiedName;

Method definitions for methods contained in System.Xml.XMLReader

I haven't been able to find a reference that defines what these methods are made up of.
I kind of get what these methods do and what arguments they take, but I'm hoping to find out how they work.
I'd like to find something that would give me a definition such as
void System.Xml.Xmlreader()
{
//class constructor function
}
for all or most of the methods in this class.
The method signatures are available on MSDN:
http://msdn.microsoft.com/en-us/library/system.xml.xmlreader_methods.aspx
If you click on the method names, you'll see a definition, explanation, and usually some code examples.
Edit: Also, if you right click on the using directive and choose "Go to Definition" in Visual Studio, you can view the metadata for the class.

Categories