Have browsed, searched and hoped but cannot find a straight answer.
Is there anyway in C# 6.0 to get the current method name using nameof withouth specifying the method name?
I am adding my test results to a dictionary like this:
Results.Add(nameof(Process_AddingTwoConsents_ThreeExpectedRowsAreWrittenToStream), result);
I would prefer if I would not have to specify the method name explicitly so I can copy+paste the line, a non-working example:
Results.Add(nameof(this.GetExecutingMethod()), result);
If possible I do not want to use Reflection.
UPDATE
This is not (as suggested) a duplicate of this question. I am asking if is explicitly possible to make use of nameof without(!) reflection to get the current method name.
You can't use nameof to achieve that, but how about this workaround:
The below uses no direct reflection (just like nameof) and no explicit method name.
Results.Add(GetCaller(), result);
public static string GetCaller([CallerMemberName] string caller = null)
{
return caller;
}
GetCaller returns the name of any method that calls it.
Building on user3185569's great answer:
public static string GetMethodName(this object type, [CallerMemberName] string caller = null)
{
return type.GetType().FullName + "." + caller;
}
Results in you being able to call this.GetMethodName() anywhere to return the fully qualified method name.
Same as others, but some variation:
/// <summary>
/// Returns the caller method name.
/// </summary>
/// <param name="type"></param>
/// <param name="caller"></param>
/// <param name="fullName">if true returns the fully qualified name of the type, including its namespace but not its assembly.</param>
/// <returns></returns>
public static string GetMethodName(this object type, [CallerMemberName] string caller = null, bool fullName = false)
{
if (type == null) throw new ArgumentNullException(nameof(type));
var name = fullName ? type.GetType().FullName : type.GetType().Name;
return $"{name}.{caller}()";
}
Allows to call it like this:
Log.Debug($"Enter {this.GetMethodName()}...");
If you want to add the name of the current method into the Results List then you may use this :
StackTrace sTrace= new StackTrace();
StackFrame sFrame= sTrace.GetFrame(0);
MethodBase currentMethodName = sFrame.GetMethod();
Results.Add(currentMethodName.Name, result);
Or you can use,
Results.Add(new StackTrace().GetFrame(0).GetMethod().Name, result);
Related
I've not been able to find any examples at all for this.
Here is what I am currently doing:
public partial class RenameGroupPopupViewModel
{
private string _newGroupName;
public string NewGroupName
{
get => _newGroupName;
set => SetProperty(ref _newGroupName, value);
}
}
In ObservableObject.cs there is a parameter validateValue but I do not know or understand how to use it.
I would like to try using the Func<T, T, bool>? validateValue = null) to call a method called ValidateName that would check if the value is set to "default" and if so then return false so the value would not be set.
Here is the full code for the class:
ObservableObject.cs
Here is the code snippet from
/// <summary>
/// Sets the property.
/// </summary>
/// <returns><c>true</c>, if property was set, <c>false</c> otherwise.</returns>
/// <param name="backingStore">Backing store.</param>
/// <param name="value">Value.</param>
/// <param name="validateValue">Validates value.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="onChanged">On changed.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
protected virtual bool SetProperty<T>(
ref T backingStore,
T value,
[CallerMemberName] string propertyName = "",
Action? onChanging = null,
Action? onChanged = null,
Func<T, T, bool>? validateValue = null)
{
// if value didn't change
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
// if value changed but didn't validate
if (validateValue != null && !validateValue(backingStore, value))
return false;
onChanging?.Invoke();
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
I realize I have to supply a function for the validation but I am not sure how to specify this and should it be a normal kind of method or a delegate? Here is the functionality I need:
private bool ValidateName(string groupName)
{
if (groupName == "default")
return false;
else
return true;
}
The method you're calling contains this clause:
// if value changed but didn't validate
if (validateValue != null && !validateValue(backingStore, value))
return false;
This is invoking the validateValue delegate that's passed in. The delegate takes two parameters, both of type T for the generic SetProperty<T>() method, and returns a bool, where false means that the values passed to the delegate don't meet whatever criteria the caller has implemented for the delegate.
Note that backingStore, which is the current value of the property, and value, which is the new value being assigned to the property, are both passed to the validation delegate. So the delegate is free to use either or both as it sees fit.
Your chosen method appears to care only about the newly-assigned value. So you can pass an appropriate delegate either by changing your validation method signature to accept two parameters and ignoring the first one:
private bool ValidateName(string currentName, string newName)
{
if (newName == "default")
return false;
else
return true;
}
and
public string NewGroupName
{
get => _newGroupName;
set => SetProperty(ref _newGroupName, value, validateValue: ValidateName);
}
Or you can leave your method as it is now, and wrap a call to it in a lambda expression:
public string NewGroupName
{
get => _newGroupName;
set => SetProperty(ref _newGroupName, value, validateValue: (_, newName) => ValidateName(newValue));
}
Either one would be fine.
Note the use of the named parameter, since there are additional parameters between the value argument being passed and the delegate reference being passed which you presumably still don't want to specify. Naming the validateValue parameter allows the other parameters to still be omitted, resulting in their default values being passed as expected.
Note also that in either case, a delegate instance is what's actually passed. The C# compiler automatically translates expressions such as a "method group name", as in the first example, or a "lambda expression", as in the second example, into code that instantiates a new delegate instance, using the provided method as the target of the delegate, inferring the delegate type according to the context of the code (in this example, the actual delegate type being passed will be Func<string, string, bool>). Lambda expressions of this form are compiled as "anonymous methods". You can look those terms up for additional information if you like.
I have a method with an out parameter that tries to do a type conversion. Basically:
public void GetParameterValue(out object destination)
{
object paramVal = "I want to return this. could be any type, not just string.";
destination = null; // default out param to null
destination = Convert.ChangeType(paramVal, destination.GetType());
}
The problem is that usually someone would call this like:
string output;
GetParameterValue(output);
This will fail because of:
destination.GetType()
destination is null, so we can't call .GetType() on it. We also can not call:
typeof(destination)
because destination is a variable name not a type name.
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Just to give a bit more info, I am trying to make a utility method that will grab the output parameters of an Oracle stored procedure. The issue is that DbParameter.Value is of type object.
What would be ideal would be for the developers to do something like:
string val = GetParameterValue("parameterName");
The notable thing is that there is no casting of types. In practice, you don't know the lparam of the "equals", so I went with:
string val;
GetParameterValue("parameterName", out val);
And figured within the method, I would know the destination type of the output variable. I guess that was a bad assumption. As an alternative, I also wrote the method:
public T GetParameterValue<T>(string paramName)
So the developers can do:
string val = GetParameterValue<string>("parameterName");
I find the explicit "string" declaration to be repetitive, especially since in practice, the destination if probably an object property and the oracle data type could change (think ORM):
MyObj.SomeProp = GetParameterValue<MyObj.SomeProp.GetType()>("parameterName");
But again, if MyObj.SomeProp is null, that .GetType() call fails. The VM has to know the type of MyObj.SomeProp, even when its null, right? or else how would it catch cast exceptions?
To partially solve my own problem, I can do:
MyObj.SomeProp = GetParameterValue<typeof(MyObj).GetField("SomeProp").GetType()>("parameterName");
The whole idea was to not have to explicitly use the Type in more than one place, so that if the data type changes, it only has to be changed in the destination object (MyObj.SomeProp) and in the DB. There has to be a better way...
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Not necessarily. The best that you can say is that it is an object. A null reference does not point to any storage location, so there is no metadata from which it can make that determination.
The best that you could do is change it to be more generic, as in:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
It's possible if you don't mind declaring your method as a generic. Try this.
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
The following extension method returns the type of its parameter as it was declared, regardless of its contents:
using System;
namespace MyNamespace
{
public static class Extensions
{
/// <summary>
/// Gets the declared type of the specified object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <returns>
/// A <see cref="Type"/> object representing type
/// <typeparamref name="T"/>; i.e., the type of <paramref name="obj"/>
/// as it was declared. Note that the contents of
/// <paramref name="obj"/> are irrelevant; if <paramref name="obj"/>
/// contains an object whose class is derived from
/// <typeparamref name="T"/>, then <typeparamref name="T"/> is
/// returned, not the derived type.
/// </returns>
public static Type GetDeclaredType<T>(
this T obj )
{
return typeof( T );
}
}
}
Since this is an extension method, its argument can be a null reference, and all of the following works OK:
string myString = "abc";
object myObj = myString;
Type myObjType = myObj.GetDeclaredType();
string myNullString = null;
object myNullObj = myNullString;
Type myNullObjType = myNullObj.GetDeclaredType();
Note that myObjType and myNullObjType will both be set to System.Object, not System.String.
If you actually want the type of obj's contents when it's not null, then change the return line to:
return (obj != null) ? obj.GetType() : typeof( T );
Currently, you have no way of knowing what gets passed into the method. You can convert it into a generic method like this:
public void GetParameterValue<T>(out T destination)
{
...
}
The type of your destination variable is always System.Object. You could just return
Convert.ChangeType(paramVal, System.Object).
#Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You might consider passing the Type as a parameter to GetParameterValue where you have more information, such as:
public void GetParameterValue(Type sourceType, out object destination) { //... }
If there is no instance, there is no instance type.
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
In your example it would be null of type System.Object.
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
One could do the following for this line:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
or
private Hashtable propertyTable = new Hashtable();
public void LoadPropertyTypes()
{
Type t = this.GetType();
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
{
string[] prop = mInfo.ToString().Split(Convert.ToChar(" "));
propertyTable.Add(prop[1], prop[0]);
}
}
public string GetMemberType(string propName)
{
if (propertyTable.ContainsKey(propName))
{
return Convert.ToString(propertyTable[propName]);
}
else{
return "N/A";
}
}
in that way we can use switch to manage different property types.
I would like to add a completion suggestion of nameof to a parameter in a method.
The method:
public static class Ensure
{
/// <summary>
/// throws <see cref="ArgumentException"/> exception if string is null or empty.
/// </summary>
/// <param name="value">string to check its content.</param>
/// <param name="name">name of parameter passed.</param>
public static void StringNotNullOrEmpty(string value, string name)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Value cannot be null or empty", name);
}
}
}
When typing Ensure.StringNotNullOrEmpty(testString, <...>) I would like to get the nameof(testString) suggestion for <...>. The above method doesn't suggest the nameof (Worse still, after typing 'n' I only get suggestions as null, new). The nameof(...) is necessary so I get the correct ParamName in the ArgumentException.
On the site of Resharper it says that ArgumentNullException makes use of the nameof suggestion by using the InvokerParameterNameAttribute (source: Resharper InvokerParameterNameAttribute).
Attempt:
So I installed the nuget package in my project: JetBrains.Annotations 10.4.0 and changed the method as followed:
public static class Ensure
{
/// <summary>
/// throws <see cref="ArgumentException"/> exception if string is null or empty.
/// </summary>
/// <param name="value">string to check its content.</param>
/// <param name="name">name of parameter passed.</param>
public static void StringNotNullOrEmpty([CanBeNull] string value,
[NotNull] [InvokerParameterName] string name)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Value cannot be null or empty", name);
}
}
}
Unfortunately the above attempt is still not giving me the suggestion of nameof when I've typed: Ensure.StringIsNotNullOrEmpty(testString,.
Some other thing I found was the CallerMemberNameAttribute on MSDN. But this only gives me the name of the calling method as a string.
I also looked into some repo's on GitHub, and could only find solutions the same way as my attempt.
One reason I can think of is when having two string parameters in a method with an InvokerParameterNameAttribute defined on the latter, it could be confusing for Resharper.
Is it possible to add the nameof suggestion for a parameter in a method? And how can I achieve this with the above method?
Additional info:
I have VS2015 + Resharper 2016.3.2.
actually that works (but not as you intended). it will not suggest as soon as you type ,... it will only suggest you to use nameof expression when you fully type name of argument in form of string instead of using nameof expression.
static void Caller(string arg)
{
StringNotNullOrEmpty(arg, "arg"); // only now resharper suggests to use nameof.
StringNotNullOrEmpty(arg, "something else"); // now resharper complains about unknown argument name.
}
You can submit feedback on resharper to actually implement the behavior you want.
Also if you type "" the cursor will move to middle of double quotes and resharper suggests name of available parameters.
BTW you can always comment your code that can be useful for every future readers
/// <summary>
/// throws <see cref="ArgumentException"/> exception if string is null or empty.
/// </summary>
/// <param name="value">string to check its content.</param>
/// <param name="name">name of parameter passed.</param>
public static void StringNotNullOrEmpty([CanBeNull] string value,
[NotNull] [InvokerParameterName] string name)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Value cannot be null or empty", name);
}
}
I have a method with an out parameter that tries to do a type conversion. Basically:
public void GetParameterValue(out object destination)
{
object paramVal = "I want to return this. could be any type, not just string.";
destination = null; // default out param to null
destination = Convert.ChangeType(paramVal, destination.GetType());
}
The problem is that usually someone would call this like:
string output;
GetParameterValue(output);
This will fail because of:
destination.GetType()
destination is null, so we can't call .GetType() on it. We also can not call:
typeof(destination)
because destination is a variable name not a type name.
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Just to give a bit more info, I am trying to make a utility method that will grab the output parameters of an Oracle stored procedure. The issue is that DbParameter.Value is of type object.
What would be ideal would be for the developers to do something like:
string val = GetParameterValue("parameterName");
The notable thing is that there is no casting of types. In practice, you don't know the lparam of the "equals", so I went with:
string val;
GetParameterValue("parameterName", out val);
And figured within the method, I would know the destination type of the output variable. I guess that was a bad assumption. As an alternative, I also wrote the method:
public T GetParameterValue<T>(string paramName)
So the developers can do:
string val = GetParameterValue<string>("parameterName");
I find the explicit "string" declaration to be repetitive, especially since in practice, the destination if probably an object property and the oracle data type could change (think ORM):
MyObj.SomeProp = GetParameterValue<MyObj.SomeProp.GetType()>("parameterName");
But again, if MyObj.SomeProp is null, that .GetType() call fails. The VM has to know the type of MyObj.SomeProp, even when its null, right? or else how would it catch cast exceptions?
To partially solve my own problem, I can do:
MyObj.SomeProp = GetParameterValue<typeof(MyObj).GetField("SomeProp").GetType()>("parameterName");
The whole idea was to not have to explicitly use the Type in more than one place, so that if the data type changes, it only has to be changed in the destination object (MyObj.SomeProp) and in the DB. There has to be a better way...
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Not necessarily. The best that you can say is that it is an object. A null reference does not point to any storage location, so there is no metadata from which it can make that determination.
The best that you could do is change it to be more generic, as in:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
It's possible if you don't mind declaring your method as a generic. Try this.
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
The following extension method returns the type of its parameter as it was declared, regardless of its contents:
using System;
namespace MyNamespace
{
public static class Extensions
{
/// <summary>
/// Gets the declared type of the specified object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <returns>
/// A <see cref="Type"/> object representing type
/// <typeparamref name="T"/>; i.e., the type of <paramref name="obj"/>
/// as it was declared. Note that the contents of
/// <paramref name="obj"/> are irrelevant; if <paramref name="obj"/>
/// contains an object whose class is derived from
/// <typeparamref name="T"/>, then <typeparamref name="T"/> is
/// returned, not the derived type.
/// </returns>
public static Type GetDeclaredType<T>(
this T obj )
{
return typeof( T );
}
}
}
Since this is an extension method, its argument can be a null reference, and all of the following works OK:
string myString = "abc";
object myObj = myString;
Type myObjType = myObj.GetDeclaredType();
string myNullString = null;
object myNullObj = myNullString;
Type myNullObjType = myNullObj.GetDeclaredType();
Note that myObjType and myNullObjType will both be set to System.Object, not System.String.
If you actually want the type of obj's contents when it's not null, then change the return line to:
return (obj != null) ? obj.GetType() : typeof( T );
Currently, you have no way of knowing what gets passed into the method. You can convert it into a generic method like this:
public void GetParameterValue<T>(out T destination)
{
...
}
The type of your destination variable is always System.Object. You could just return
Convert.ChangeType(paramVal, System.Object).
#Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You might consider passing the Type as a parameter to GetParameterValue where you have more information, such as:
public void GetParameterValue(Type sourceType, out object destination) { //... }
If there is no instance, there is no instance type.
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
In your example it would be null of type System.Object.
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
One could do the following for this line:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
or
private Hashtable propertyTable = new Hashtable();
public void LoadPropertyTypes()
{
Type t = this.GetType();
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
{
string[] prop = mInfo.ToString().Split(Convert.ToChar(" "));
propertyTable.Add(prop[1], prop[0]);
}
}
public string GetMemberType(string propName)
{
if (propertyTable.ContainsKey(propName))
{
return Convert.ToString(propertyTable[propName]);
}
else{
return "N/A";
}
}
in that way we can use switch to manage different property types.
In my reflection code i hit a problem with my generic section of code. Specifically when i use a string.
var oVal = (object)"Test";
var oType = oVal.GetType();
var sz = Activator.CreateInstance(oType, oVal);
Exception
An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll
Additional information: Constructor on type 'System.String' not found.
I tried this for testing purposes and it occurs in this single liner too
var sz = Activator.CreateInstance("".GetType(), "Test");
originally i wrote
var sz = Activator.CreateInstance("".GetType());
but i get this error
Additional information: No parameterless constructor defined for this object.
How do i create a string using reflection?
Keep in mind that the string class is immutable. It cannot be changed after it is created. That explains why it doesn't have a parameterless constructor, it could never generate a useful string object other than an empty string. That's already available in the C# language, it is "".
Same reasoning applies for a string(String) constructor. There is no point in duplicating a string, the string you'd pass to the constructor is already a perfectly good instance of the string.
So fix your problem by testing for the string case:
var oType = oVal.GetType();
if (oType == typeof(string)) return oVal as string;
else return Activator.CreateInstance(oType, oVal);
You are trying to do this :
var sz = new string();
Try to compile it, you will understand your error.
You may try :
var sz = Activator.CreateInstance(typeof(string), new object[] {"value".ToCharArray()});
But it looks useless, you should directly use value...
It looks like you're trying to call a constructor which just takes a string - and there isn't such a constructor. If you've already got a string, why are you trying to create a new one? (When you didn't provide any further arguments, you were trying to call a parameterless constructor - which again, doesn't exist.)
Note that typeof(string) is a simpler way to get a reference to the string type.
Could you give us more information about the bigger picture of what you're trying to do?
String actually has no constructor that takes a string as input. There is a constructor that takes a char array so this should work:
var sz = Activator.CreateInstance ("".GetType (), "Test".ToCharArray ());
This is what I use in my projects. As far as needing to create an instantiation of a type of object and not knowing at design time, is rather normal for me. Perhaps you are cycling through object properties and you want to instantiate all of them dynamically. I have many times needed to create then assign values to non instantiated POCO objects... with the below code you can use a string value stored in the DB to instantiate an object as well or instantiate an object stored in a library that is referencing your library - so you can bypass circular reference errors as well... Hope it helps.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
/// <summary>
/// Instantiates an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate
/// returns instantiated object
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
public static object Create(string typeAssemblyQualifiedName)
{
// resolve the type
Type targetType = ResolveType(typeAssemblyQualifiedName);
if (targetType == null)
throw new ArgumentException("Unable to resolve object type: " + typeAssemblyQualifiedName);
return Create(targetType);
}
/// <summary>
/// create by type of T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Create<T>()
{
Type targetType = typeof(T);
return (T)Create(targetType);
}
/// <summary>
/// general object creation
/// </summary>
/// <param name="targetType"></param>
/// <returns></returns>
public static object Create(Type targetType)
{
//string test first - it has no parameterless constructor
if (Type.GetTypeCode(targetType) == TypeCode.String)
return string.Empty;
// get the default constructor and instantiate
Type[] types = new Type[0];
ConstructorInfo info = targetType.GetConstructor(types);
object targetObject = null;
if (info == null) //must not have found the constructor
if (targetType.BaseType.UnderlyingSystemType.FullName.Contains("Enum"))
targetObject = Activator.CreateInstance(targetType);
else
throw new ArgumentException("Unable to instantiate type: " + targetType.AssemblyQualifiedName + " - Constructor not found");
else
targetObject = info.Invoke(null);
if (targetObject == null)
throw new ArgumentException("Unable to instantiate type: " + targetType.AssemblyQualifiedName + " - Unknown Error");
return targetObject;
}
/// <summary>
/// Loads the assembly of an object. Must pass PropertyType.AssemblyQualifiedName for factory to operate
/// Returns the object type.
/// </summary>
/// <param name="typeString"></param>
/// <returns></returns>
public static Type ResolveType(string typeAssemblyQualifiedName)
{
int commaIndex = typeAssemblyQualifiedName.IndexOf(",");
string className = typeAssemblyQualifiedName.Substring(0, commaIndex).Trim();
string assemblyName = typeAssemblyQualifiedName.Substring(commaIndex + 1).Trim();
if (className.Contains("[]"))
className.Remove(className.IndexOf("[]"), 2);
// Get the assembly containing the handler
Assembly assembly = null;
try
{
assembly = Assembly.Load(assemblyName);
}
catch
{
try
{
assembly = Assembly.LoadWithPartialName(assemblyName);//yes yes this is obsolete but it is only a backup call
}
catch
{
throw new ArgumentException("Can't load assembly " + assemblyName);
}
}
// Get the handler
return assembly.GetType(className, false, false);
}