I am writing a program which needs the namespace of the program but I cant seem to figure out how to retrieve it. I would like the end result to be in a string.
I was able to find an MSDN page about this topic but it proved to be unhelpful to myself.
http://msdn.microsoft.com/en-us/library/system.type.namespace.aspx
Any help would be appreciated. The program is written in C#.
EDIT: Sorry guys, this is not a console application.
This should work:
var myType = typeof(MyClass);
var n = myType.Namespace;
Write out to the console:
Type myType = typeof(MyClass);
Console.WriteLine("Namespace: {0}.", myType.Namespace);
Setting a WinForm label:
Type myType = typeof(MyClass);
namespaceLabel.Text = myType.Namespace;
Or create a method in the relevant class and use anywhere:
public string GetThisNamespace()
{
return GetType().Namespace;
}
To add to all the answers.
Since C# 6.0 there is the nameof keyword.
string name = nameof(MyNamespace);
This has several advantages:
The name is resolved at compile-time
The name will change when refactoring the namespace
It is syntax checked, so the name must exist
cleaner code
Note: This doesn't give the full namespace though. In this case, name will be equal to Bar:
namespace Foo.Bar
{
string name = nameof(Foo.Bar);
}
Put this to your assembly:
public static string GetCurrentNamespace()
{
return System.Reflection.Assembly.GetExecutingAssembly().EntryPoint.DeclaringType.Namespace;
}
Or if you want this method to be in a library used by your program, write it like this:
[System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.NoInlining)]
public static string GetCurrentNamespace()
{
return System.Reflection.Assembly.GetCallingAssembly().EntryPoint.DeclaringType.Namespace;
}
This can't go wrong:
MethodBase.GetCurrentMethod().DeclaringType.Namespace
if you have item x of class A in namespace B you can use:
string s = x.GetType().Namespace;
no s contains "B"
you can also use x.GetType().Name to get the type name or x.GetType().FullName to get both
You could simply use typeof and then pass in the class (I.e. Program):
Console.WriteLine(typeof(Program).Namespace);
Which would print:
ConsoleApplication1
Type myType = typeof(MyClass);
// Get the namespace of the myClass class.
Console.WriteLine("Namespace: {0}.", myType.Namespace);
Building on Joe's comment you can still use
Type myType = typeof(MyClass);
// Get the namespace of the myClass class.
var namespaceName = myType.Namespace.ToString();
with namespaceName being a variable to access the namespace name as a string value.
If you're executing it from a class in the namespace you need to capture then you can just use:
GetType().Namespace
This works nicely as it then allows you to refactor the namespace and will still work.
as a roll upp all post answers:
getting all columns' values from a table given as a string tableName:
var tableName = "INVENTORY_PRICE";
var assembly = Assembly.GetExecutingAssembly();
var tip = typeof(Form3);
var t = assembly.GetType(tip.Namespace + "." + tableName);
if (t != null)
{
var foos = db.GetTable(t);
foreach (var f in foos)
{
Console.WriteLine(f + ":");
foreach (var property in f.GetType().GetProperties())
if (property != null)
{
var pv = property.GetValue(f, null);
Console.WriteLine(" " + property.Name + ":" + pv);
}
Console.WriteLine("------------------------------------------------");
}
}
it is very easy if we use ado, this sample uses LINQ context...
Related
I'm trying to create a method that counts the properties of a given class.
I want to pass in the class name as a string perhaps and then can turn the string into a reference of the given class. I have literally hundreds of classes (generated by Thrift) that could be passed in, so its not practical to give each class its own property counter.
My purpose is to provide arguments to a class that dynamically creates a UI based on what will need to be input by the user for each specific method and what will be returned. To save myself from having to manually write a UI for every method.
Is there a good way to do this?
Here's what I have so far.
class PropertyCounter
{
public int PropertyCounter(string nameOfClass)
{
int count = typeof(nameOfClass).GetProperties().Count();
return count
}
}
I got this working... using Assembly. Took some doing but it does what i need it to do.
Now, I was thinking of making these into a list of 'class' objects, but I'm thinking a string would work just as well for an argument.
Thanks to all who offered assistance.
class Discover
{
public void DiscoverProperties()
{
var me = Assembly.GetExecutingAssembly().Location;
var dir = Path.GetDirectoryName(me);
var theClasses = dir + #"dllName.dll";
var assembly = Assembly.LoadFrom(theClasses);
var types = assembly.ExportedTypes.ToList();
int propCount;
string propertiesList;
string cName;
string tempString;
foreach (var t in types)
{
propertiesList = "";
propCount = 0;
cName = t.Name;
foreach (var prop in t.GetProperties())
{
propCount++;
tempString = $"{prop.Name}:{prop.PropertyType.Name} ";
propertiesList = propertiesList += tempString;
}
}
}
}
You could use Activator.CreateInstance, with the overload which accepts two strings: one for the assembly in which the type is located, and one which specifies the type (in your case, class).
https://msdn.microsoft.com/en-us/library/d133hta4(v=vs.110).aspx
public int PropertyCounter(string nameOfClass) {
return Activator.CreateInstance(nameOfAssembly,
nameOfClass).GetType().GetProperties().Count();
}
You should check for failure
I want to get a namespace string from a strongly typed namespace reference in a similar way as C# 6 nameof() works for types and type members.
namespace This.Is.My.Namespace
{
class Program
{
static void Main()
{
string namespaceString = nameof(This.Is.My.Namespace);
Console.Write(namespaceString);
}
}
}
But the result i get is only the last portion of the namespace (e.g. "Namespace"). I'm targeting .NET 4.6
Is this possible?
REMARK: I want to be able to reference any available namespace, not only the containing one.
This should work...
var myType = this.GetType();
var namespaceString = myType.Namespace;
nameof is replaced at compile time with string, where string is an exact text of that member (as if you would put it yourself inside "").
To achieve what you want you can construct something monstrous-like:
namespace This.Is.My.Namespace
...
var namespaceString = $"{nameof(This)}.{nameof(This.Is)}.{nameof(This.Is.My)}.{nameof(This.Is.My.Namespace)}";
This will ensure what every member exists at compile-time and allow easy refactoring of either (well, unless you decide to add/delete some names).
P.S.: but obviously other answers are more efficient at generating same string.
For string use below code
Type myType = typeof(MyClass);
var n = myType.Namespace;
Type myType = typeof(MyClass);
Console.WriteLine("Namespace: {0}.", myType.Namespace);
I've been looking at return values for Type.Namespace, Type.Name, Type.FullName, and Type.AssemblyQualifiedName. There are inconsistencies.
For an inner class like ConsoleApplication8.Program+InnerClass, Namespace returns ConsoleApplication8 and Name returns InnerClass, omitting Program, so concatenating Type.NameSpace and Type.Name would be an incomplete representation of the class name (just as an example).
Even the FullName property is inconsistent. Although it omits assembly name and returns ConsoleApplication8.Program+InnerClass for such an inner class, FullName includes the assembly name in the generic arguments for a type such as List<long> (even though it's omitted for the outer generic type itself, so I guess there is some level of consistency there).
I am currently using this code with a cached type name lookup that uses the CodeDom to produce real C# code names. Basically, I'm trying to reverse the process to get the type, given a real class name.
static System.Collections.Concurrent.ConcurrentDictionary<Type, string> typeNameCache = new System.Collections.Concurrent.ConcurrentDictionary<Type, string>();
static string GetTypeName(Type type)
{
string name;
if (!typeNameCache.TryGetValue( type, out name ))
{
var codeDomProvider = CodeDomProvider.CreateProvider("C#");
var typeReferenceExpression = new CodeTypeReferenceExpression(new CodeTypeReference(type));
using (var writer = new StringWriter())
{
codeDomProvider.GenerateCodeFromExpression(typeReferenceExpression, writer, new CodeGeneratorOptions());
name = writer.GetStringBuilder().ToString();
}
typeNameCache.TryAdd( type, name );
}
return name;
}
The above function produces friendly C# name like System.Collections.Generic.List<long>. But it also produces names like ConsoleApplication8.Program.InnerClass (i.e. it uses a dot instead of a plus sign between Program and InnerClass). The problem is that calling Type.GetType(name) won't work, because it would require the plus sign to be there, and in addition it sometimes requires the assembly name.
So how can I get a references to a Type object, given a friendly C# class name as it would be referenced in code?
I've managed to achieve this now with a single line of code in each direction translating to and from friendly type names and runtime Type instances. Incredible. And some said it was not possible at all, lol. Flawless.
static Type GetType( string friendlyName )
{
return (Type)(new CSharpCodeProvider().CompileAssemblyFromSource( new CompilerParameters( AppDomain.CurrentDomain.GetAssemblies().SelectMany<Assembly,string>( a => a.GetModules().Select<Module,string>( m => m.FullyQualifiedName )).ToArray(), null, false) {GenerateExecutable = false, GenerateInMemory = true, TreatWarningsAsErrors = false, CompilerOptions = "/optimize"}, "public static class C{public static System.Type M(){return typeof(" + friendlyName + ");}}").CompiledAssembly.GetExportedTypes()[0].GetMethod("M").Invoke( null, System.Reflection.BindingFlags.Static, null, null, null ));
}
static string GetFriendlyName( Type type )
{
return new CSharpCodeProvider().GetTypeOutput(new CodeTypeReference(type));
}
The above code (first method only), when expanded to multiple lines looks like the following. You can just make a call like GetType("System.Collections.Generic.List<int>"); and it will return a type reference.
static Type GetType( string friendlyName )
{
var currentlyLoadedModuleNames = AppDomain.CurrentDomain.GetAssemblies().SelectMany<Assembly,string>( a => a.GetModules().Select<Module,string>( m => m.FullyQualifiedName )).ToArray();
var csc = new CSharpCodeProvider();
CompilerResults results = csc.CompileAssemblyFromSource(
new CompilerParameters( currentlyLoadedModuleNames, "temp.dll", false) {
GenerateExecutable = false, GenerateInMemory = true, TreatWarningsAsErrors = false, CompilerOptions = "/optimize"
},
#"public static class TypeInfo {
public static System.Type GetEmbeddedType() {
return typeof(" + friendlyName + #");
}
}");
if (results.Errors.Count > 0)
throw new Exception( "Error compiling type name." );
Type[] type = results.CompiledAssembly.GetExportedTypes();
return (Type)type[0].GetMethod("GetEmbeddedType").Invoke( null, System.Reflection.BindingFlags.Static, null, null, null );
}
Update: I added a line to make all the modules loaded in the current app domain available to the compiler. That should guarantee that this is able to acquire any type by name as if you had referenced it directly in your code, with the exception that the desired types have to be public, since they are essentially referenced from an external assembly from within the compiler rather than directly in the currently executing assembly.
Just as as test, the returned type should work in a cache, since:
Type t = GetType( "System.Collections.Generic.List<int>" );
Console.WriteLine( typeof(System.Collections.Generic.List<int>) == t );
//RETURNS TRUE
So, basically per our conversation in the comments the goal here is to get a type object (for whatever purpose) from a name of the type. Calling "Type.GetType()" works for simple types but for generics and other types it doesn't work because the name needs to be qualified. The key, then is to use the code compiler to actually have the C# code engine find and get the type. The following is a working program that does just that:
using System;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
namespace SimpleCompileTest
{
class Program
{
public static void Main(string[] args)
{
string typeName = "System.Collections.Generic.List<int>";
Type theType = GetTypeFromName(typeName);
}
private static Type GetTypeFromName(string typeName)
{
// double open and close are for escape purposes
const string typeProgram = #"using System; using System.Collections.Generic; using System.IO;
namespace SimpleTest
{{
public class Program
{{
public static Type GetItemType()
{{
{0} typeTest = new {0}();
if (typeTest == null) return null;
return typeTest.GetType();
}}
}}
}}";
var formattedCode = String.Format(typeProgram, typeName);
var CompilerParams = new CompilerParameters
{
GenerateInMemory = true,
TreatWarningsAsErrors = false,
GenerateExecutable = false,
CompilerOptions = "/optimize"
};
string[] references = { "System.dll" };
CompilerParams.ReferencedAssemblies.AddRange(references);
var provider = new CSharpCodeProvider();
CompilerResults compile = provider.CompileAssemblyFromSource(CompilerParams, formattedCode);
if (compile.Errors.HasErrors) return null;
Module module = compile.CompiledAssembly.GetModules()[0];
Type mt = null; MethodInfo methInfo = null;
if (module != null) mt = module.GetType("SimpleTest.Program");
if (mt != null) methInfo = mt.GetMethod("GetItemType");
if (methInfo != null) return (Type)methInfo.Invoke(null, null);
return null;
}
}
}
One really important thing to note - you need to add the list of assemblies to the compiler that you hope to pull types from. That means if you have a custom type that you want to reference you need to provide that to the compiler, but otherwise, this works! Enjoy!
I am writing a program which needs the namespace of the program but I cant seem to figure out how to retrieve it. I would like the end result to be in a string.
I was able to find an MSDN page about this topic but it proved to be unhelpful to myself.
http://msdn.microsoft.com/en-us/library/system.type.namespace.aspx
Any help would be appreciated. The program is written in C#.
EDIT: Sorry guys, this is not a console application.
This should work:
var myType = typeof(MyClass);
var n = myType.Namespace;
Write out to the console:
Type myType = typeof(MyClass);
Console.WriteLine("Namespace: {0}.", myType.Namespace);
Setting a WinForm label:
Type myType = typeof(MyClass);
namespaceLabel.Text = myType.Namespace;
Or create a method in the relevant class and use anywhere:
public string GetThisNamespace()
{
return GetType().Namespace;
}
To add to all the answers.
Since C# 6.0 there is the nameof keyword.
string name = nameof(MyNamespace);
This has several advantages:
The name is resolved at compile-time
The name will change when refactoring the namespace
It is syntax checked, so the name must exist
cleaner code
Note: This doesn't give the full namespace though. In this case, name will be equal to Bar:
namespace Foo.Bar
{
string name = nameof(Foo.Bar);
}
Put this to your assembly:
public static string GetCurrentNamespace()
{
return System.Reflection.Assembly.GetExecutingAssembly().EntryPoint.DeclaringType.Namespace;
}
Or if you want this method to be in a library used by your program, write it like this:
[System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.NoInlining)]
public static string GetCurrentNamespace()
{
return System.Reflection.Assembly.GetCallingAssembly().EntryPoint.DeclaringType.Namespace;
}
This can't go wrong:
MethodBase.GetCurrentMethod().DeclaringType.Namespace
if you have item x of class A in namespace B you can use:
string s = x.GetType().Namespace;
no s contains "B"
you can also use x.GetType().Name to get the type name or x.GetType().FullName to get both
You could simply use typeof and then pass in the class (I.e. Program):
Console.WriteLine(typeof(Program).Namespace);
Which would print:
ConsoleApplication1
Type myType = typeof(MyClass);
// Get the namespace of the myClass class.
Console.WriteLine("Namespace: {0}.", myType.Namespace);
Building on Joe's comment you can still use
Type myType = typeof(MyClass);
// Get the namespace of the myClass class.
var namespaceName = myType.Namespace.ToString();
with namespaceName being a variable to access the namespace name as a string value.
If you're executing it from a class in the namespace you need to capture then you can just use:
GetType().Namespace
This works nicely as it then allows you to refactor the namespace and will still work.
as a roll upp all post answers:
getting all columns' values from a table given as a string tableName:
var tableName = "INVENTORY_PRICE";
var assembly = Assembly.GetExecutingAssembly();
var tip = typeof(Form3);
var t = assembly.GetType(tip.Namespace + "." + tableName);
if (t != null)
{
var foos = db.GetTable(t);
foreach (var f in foos)
{
Console.WriteLine(f + ":");
foreach (var property in f.GetType().GetProperties())
if (property != null)
{
var pv = property.GetValue(f, null);
Console.WriteLine(" " + property.Name + ":" + pv);
}
Console.WriteLine("------------------------------------------------");
}
}
it is very easy if we use ado, this sample uses LINQ context...
this link: http://www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met
explains clearly how to invoke a method when you have a method name + type as string variable.
I'm making a c# project with WatiN. All the WatiN methods I use are of the same form:
Examples: *(ById,.ByClass..; so should be connected, but then I could not set it bold :s )
browser.**TextField**(Find.By **Id**("name")).**TypeText**("my name");
browser.**Span**(Find.By **Class**("main_title")).**Click(**);
browser.**Link**(Find.By **Id**("mid_link")).**Click(**);
As you can see, this always consist of 3 methods which are variable. I created a class webElement consisted of the string properties: tag, type, search, action.
Where in example -> tag = "TextField"; type = "Id", search = "name"; action = "TypeText".
To get the web-elements dynamically, I created a WebHandler class where I try to dynamically call the right methods.
So a main class has a list of all the webElement objects and can give the right one at a given time to the WebHandler class. The Webhandler class should now invoke each element dynamically. I use the same invoke method as in given url, so my code to call it is:
class WebHandler:
private IE browser = new IE("google.com");
public void method(WebElement webElement)
{
//Get the findBy dynamically | this works
WatiN.Core.Constraints.Constraint findBy =
(WatiN.Core.Constraints.Constraint)InvokeMethod("WatiN.Core.Find, WatiN.Core", "By" + webElement.Type, webElement.Search); //where type = "Id" and search = "name"
//Get the tag (like textfield, link, span) dynamically | this does not work
Type aType = Type.GetType("WatiN.Core." + webElement.Tag, "WatiN.Core") //how can I set the element variable to this type? aType element -> Does not work
aType element = (WatiN.Core.TextField)InvokeMethod("this.browser", webElement.Tag, findBy); //tag = TextField
element.TypeText("a name"); //same problem as above | so should be invoked
}
QUESTIONS:
How do I invoke method (TextField) of instance class IE
(browser) dynamically using his string version "TextField" as variable? Another way of phrasing it would be: How do I get current variable (browser) by using it's string version "browser"?
How do I set type of variable element dynamically? So when webElement.Tag = Textfield then type should be WatiN.Core.TexField
element = .. (see code)
OWN CONSIDERATIONS:
Main problem I found is that you can only invoke a method from a type, so not from an instance of that type. Is there a way to do this anyway?
This line
Type aType = Type.GetType("WatiN.Core" + webElement.Tag)
does not have a dot after Core. It seems as if Core is a namespace and should thus be separated from the Tag name.
The gist of this is you get the Type you want, then use reflection to get the methods, then invoke the given method, passing the instance in.
So, something like this:
Type aType = Type.GetType(string.Format("WatiN.Core.{0}.WatiN.Core", webElement.Tag));
MethodInfo method = aType.GetMethod("TextField");
method.Invoke(this.browser, webElement.Tag, findBy);
The key bits here are:
Get the Type
Get the Method
Invoke the method with the instance you want
There are shortcuts, and I probably don't have the specifics right for your question, but that should get you close to what you want.
Here ya go, threw this together in LINQPad, but should be more-or-less portable:
void Main()
{
WatiN.Core.Browser theBrowser = new WatiN.Core.IE("google.com");
Foo(theBrowser, "Id", "gbqfq", "TextField", "TypeText", "Search for this");
}
public void Foo(WatiN.Core.Browser browser, string findTypeBy, string search, string tagName, string elementMethodName, params object[] argsForMethod)
{
var watinCoreAsm = Assembly.LoadWithPartialName("WatiN.Core");
if(watinCoreAsm == null) return;
var watinCoreTypes = watinCoreAsm.GetTypes();
if(watinCoreTypes == null) return;
var findType = watinCoreTypes.FirstOrDefault(type => type.Name == "Find");
if(findType == null) return;
var constraintInstance = findType.GetMethod("By" + findTypeBy, new Type[]{ typeof(string) }).Invoke(null, new[]{search});
if(constraintInstance == null) return;
var browserAccessor = browser.GetType().GetMethod(tagName, new Type[]{ constraintInstance.GetType() });
if(browserAccessor == null) return;
var resultElement = browserAccessor.Invoke(browser, new[]{ constraintInstance });
if(resultElement == null) return;
var elementMethod = resultElement.GetType().GetMethod(elementMethodName);
if(elementMethod == null) return;
elementMethod.Invoke(resultElement, argsForMethod);
}