I've already read the MSDN article about it. It seems internally it is the way c# sets which is the function that is going to work as indexer(am I right?). Now, I've seen the following example:
[DefaultMemberAttribute("Main")]
public class Program {
public static void Main() {
...
}
}
Now, I don't get it what it means.
Thanks all. But I still can't get its usefulness, apart from the indexer thing. When are we going to call InvokeMember?
No, the DefaultMemberAttribute is used by languages such as VB.NET to find out the member that is acted on by default if no member is referenced from an object, i.e. the member invoked by InvokeMember. This is often used in conjunction with indexers, as you noted, but it is not used by C# directly (unless you use InvokeMember explicitly).
However, for the benefit of other .NET languages, C# does emit the DefaultMemberAttribute for the indexer of a class (if it has one), as indicated by MSDN:
The C# compiler emits the
DefaultMemberAttribute on any type
containing an indexer. In C# it is an
error to manually attribute a type
with the DefaultMemberAttribute if the
type also declares an indexer.
I think MSDN confuses things by referring to indexers a lot in the remarks but then giving an example that does not use an indexer. To clarify, the default member can be anything, but C# gives special behavior for indexers by emitting the attribute for you (if an indexer exists) to the exception of all other use cases.
I personally have never used it, but as far as I can tell you are defining the default method to be invoked when calling InvokeMember. So, using the code snippet you provided if I was to say:
Program prog = new Program();
typeof(Program).InvokeMember("", null, null, prog, null);
Because I left the first argument empty of the InvokeMember call it would use the attribute to determine what the default member is of your class, in your case it is Main.
The DefaultMemberAttribute attribute defines the default member to be called on a when InvokeMember is called with an empty string as the first argument.
If you read the MSDN docs for InvokeMember, it explicitly says:
Parameters
name
Type: System.String
The String containing the name of the constructor, method, property, or field member to invoke.
-or-
An empty string ("") to invoke the default member.
The default member will be the one declared by the DefaultMemberAttribute attribute.
Related
Today I was looking at some code of Nancy and since I like to explore the code I noticed following thing.
While navigating in VS2017 I went to NancyModule I saw the code from the metadata the following:
public virtual void Delete(string path, [Dynamic(new[] { false, true, false })] Func action, Func condition = null, string name = null);`
Now I don't know what this attribute does so I immediately went to msdn.
Parameters
transformFlags:
Type: System.Boolean[]
Specifies, in a prefix traversal of a type's construction, which Object occurrences are meant to be treated as a dynamically dispatched type.
Remarks
For instance, if C is a generic type with two type parameters, a use of the constructed type C might be intended to treat the first type argument dynamically and the second typically, in which case the appropriate attribute specification should use a transformFlags value of { false, true, false }.
After that I realized that in Nancy's code there is no such attribute applied so I thought myself "Okay, so maybe the compiler adds it." However, after decompiling this assembly with dnSpy, ilSpy I don't see such attribute at all.
So bottom line questions are:
Is this attribute intended for usage by users of .NET framework or it is only the compiler applying it (given the fact its namespace)?
What does those flags mean in its constructor? I am not sure I understand what is prefix traversal of a type's construction.
The dynamic keyword in C# does not have a dedicated type in the metadata and at runtime, it is simply object. When you add a reference to the assembly then you like to see it back as dynamic. So does the C# compiler, necessary so it can auto-generate the binder code. The [Dynamic] attribute ensures that happens.
A decompiler would do the same thing so it doesn't have to show you this attribute either. Whatever tool you used to browse the metadata wasn't that smooth about it and revealed the detail.
The C# compiler emits the attribute automatically. Nothing you have to do yourself.
I regularly want to get the name of an instance property of a type, when I have no instance. Currently to do this, I use the following inhouse function which interprets the Expression[Func[T, object]] parameter and returns the property name:
var str = LinqExtensions.NameOf<ClientService>(x => x.EndDate);
// Now str == "EndDate"
However it seems a shame not to use the built in nameof operator.
Unfortunately it seems that the nameof operator requires either an instance, or, to reference a static properties.
Is there a neat way to use the nameof operator instead of our in house function? For example:
nameof(ClientService.EndDate) // ClientService.EndDate not normally syntactically valid as EndDate is instance member
EDIT
I was completely wrong, the syntax nameof(ClientService.EndDate) as described actually works as is.
In the past, the documentation explicitly explained this, reading in part:
In the examples you see that you can use a type name and access an instance method name. You do not need to have an instance of the type… [emphasis mine]
This has been omitted in the current documentation. However, the examples still make this clear. Code samples such as Console.WriteLine(nameof(List<int>.Count)); // output: Count and Console.WriteLine(nameof(List<int>.Add)); // output: Add show how to use nameof to obtain the string value with the name of an instance member of a class.
I.e. you should be able to write nameof(ClientService.EndDate) and have it work, contrary to your observation in the question that this would be "not normally syntactically valid".
If you are having trouble with the syntax, please provide a good Minimal, Complete, and Verifiable code example that reliably reproduces whatever error you're getting, and provide the exact text of the error message.
Great answer by #Peter Duniho.
In case of name clashes, you can also do the following:
ClientService clientservice;
var str = nameof(clientservice.EndDate);
Not efficient, but curious enough.
I would like to set a const string from Settings.
In case I would like to change in the future the program language, it is quite easy;
Just have to modify the appropriate settings!
When trying this:
private const string constString =
"-&" + Properties.Settings.Default.constStringText;
I get this error:
The property or indexer 'Properties.Settings.Default'
cannot be used in this context because it lacks the get accessor.
Any idea?
Since you intend to use this as the default value for an optional method argument, that is:
public void Foo(string something = constString)
{
//do something
}
This constString must be a compile-time constant. From the MSDN page for "Named and Optional Arguments":
A default value must be one of the following types of expressions:
a constant expression;
an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;
an expression of the form default(ValType), where ValType is a value type.
As such, there really is no way to read a value from a configuration file at runtime then use it for an optional argument.
One workaround would be to instead declare your constString as a readonly field:
private readonly string constString =
"-&" + Properties.Settings.Default.constStringText;
Then make your optional argument required and create a wrapping overload for your method that doesn't take that parameter. That overload in turn calls the old method with the default value resolved at runtime:
public void Foo(string something) //no longer optional
{
//do something
}
public void Foo()
{
Foo(constString); //calls the other overload with the default value
}
This error is in 99% of cases related to a wrong namespace.
You've probably generated some class in which you are using Properties.Settings.Default
Solution: check namespace in that class file. It must be the same as the name of the tag in App.config (Web.config) where that particular setting is stored.
While Chris Sinclair’s answer (a const member must have value type and be evaluable at compile-time, so use readonly) is correct, I should like to explain these restrictions and answer the implicit question what the compiler message means, albeit with the disappointing remark that seems to be simply an error in the compiler.
The error message
The property or indexer 'Properties.Settings.Default' cannot be used in this context because it lacks the get accessor.
This message suggests that the expression Properties.Settings.Default could be made acceptable by adding a getter (and maybe something else) — as far as I know, that is simply wrong. After all, on the one hand, as the asker assured us1, there was a getter, and on the other, as Chris explains, the reason the expression is invalid is that is not evaluable at compile-time, and never can be, given that it depends on the run-time configuration.
Presumably this message is intended for other situations, and has been used here by mistake.
1 I have also seen this, in MSVS 2013, when a default parameter value referred to a property which did have a getter – but at least it also reported “Default parameter value for '<parname>' must be a compile-time constant”.
The restriction to value types
The restriction of const members and default parameter values to value types (as at the C# 5.0 Language Specification, 2012) appears to be not entirely inevitable, but an understandable consequence of other language design decisions.
A reference type can have a constructor evaluable at compile-time, but this is not supported ; perhaps this is because the language offers no way of indicating that a referenced object is immutable, nor even the concept of immutability of reference type objects. (Remember: an immutable reference to an object need not be a reference to an immutable object!)
Delegate values referring to static methods can also be considered fully determined at compile-time, as would those bound to immutable objects, were that concept supported.
Immutable arrays as constant values sound fairly easy to support.
Constant members¹ and (I believe)² default parameter values are specified to be part of the ‘interface’ of the class, in the sense that their values are to be determined at compile time and hard-coded into generated code using that class.
Resolution of the problem
You can use ( static ) readonly constString instead of const constString, to make clear that while the value will not change, it is not determined until run-time, at class or object initialisation (as in Chris’s answer).
If you want to use the expression as a default value for an optional parameter, it must be a true compile-time constant, leaving you two possibilities:
Declare an overload, as in Chris’s answer, e.g.:
Foo() { Foo(Default); } Foo(string s) { Bar(s); }.
This will often be the simpler solution, but could clutter your code and interface if you have many such parameters and thus many overloads, all with documentation comments.
Use null as a convention for the default, and interpret that in your method:
Foo(string s = null) { Bar(s != null ? s : Default); }.
This obviously only works if null is not a supported parameter to Foo(string) and should definitely be clarified in documentation comments.
Maybe: apply the Optional attribute, as in this question: behaviour of Optional attribute:
Foo([Optional] string s) { Bar(etc.?); } .
I have not used or studied this – the documentation seemed rather sparse – but it seems tricky and to yield no more than default = null, unless perhaps null is a supported argument to Foo(string).
References
¹ Language Specification 5.0 §10.5.2.2 10.5.2.2 Versioning of constants and static readonly fields
² I recall reading this, but have not found it in the Language Specification.
I recently encountered this scenario, and while searching for a solution I stumbled on this page. Based on the example above, I was able to resolve my issue like this:
private static readonly String ConStr
= string.Format("Data Source={0};Initial Catalog={1}; User ID={2}; Password={3};",
Properties.Settings.Default.DataSource,
Properties.Settings.Default.Catalog,
Properties.Settings.Default.UserID,
Properties.Settings.Default.Password);
Just wanted to share.
I have the method shown below which is generating a CA1822 Code Analysis warning. CA1822 says this:
"The 'this parameter (or 'Me' in Visual Basic) of 'ImportForm.ProcessFile(StreamReader)' is never used. Mark the member as static (or Shared in Visual Basic) or use 'this/Me' in the method body or at least one property accessor, if appropriate."
Can anyone tell me why I am getting this warning, since the 'reader' parameter is in fact being used?
private void ProcessFile(StreamReader reader)
{
string[] lines;
lines = reader.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
ParseFile.IVAFile(lines);
}
It means you use no members of the object. All the items in the method come from the parameters.
Therefore the method can safely be made static.
"reader" is being used, but you're not using "this" anywhere, so you can make the method static.
The only reason not to make it static would be if you want to use polymorphism later - e.g. making it virtual and overriding it elsewhere.
Maybe I have found malicious behavior of this message.
In a Situation like
void Print()
{
Console.Writeline(GetType().Name);
}
I get this CA1822 reported, although GetType() is an instance method.
However, I found some Explanation, why GetType() is actually not a virtual method, not an instead method, and technicly behaving like a static method.
It's just that the code Analysis does not consider this special behavior.
The warning occurs because you don't use any member variables of that class in that method. E.g.
this.m_anyVariable = anyValue;
Therefore you can/should mark that method as static.
I think it is trying to tell you that this method can be made static.
The only thing this method needs to access is "reader", but nothing from the class instance to which it belongs ("this"). In which case, you can safely make it static.
How does the system know what to use when 'this' keyword is used?
Recently, I was asked this question in an interview. Having never thought about this, I replied back saying that the system will know the current context in which the flow of control is and decide the object to be used instead of this. The interviewer didn't look pleased and he moved on to the next question.
Can anyone tell me what did the interviewer may have wanted to ask and what would be the answer?
(I think this can interpreted in different ways and hence keeping this as wiki unless someone point out not to..)
Though the answers which point out that the "this" reference is essentially passed as a magic "hidden parameter" to the call are essentially correct, the full story is actually quite a bit more complicated in C# than one might think at first glance.
Reference types are straightforward; the referenced object is checked for null and then conceptually passed as an unnamed, non-variable parameter called "this". The story is complicated by value types.
Remember, value types are, by definition, passed by value -- that is, passed by making a copy of the data. Hence their name. But clearly mutable value types -- which are pure evil and should be avoided -- cannot be passed by value as the "this", because if you called a mutator, the "this" in the mutator method would be mutating the copy, not the original!
Therefore, in a value type's method call, "this" is not the value of the receiver, it is an alias to the variable representing the storage location of the receiver. We implement this by passing "this" as the managed address of the receiver, not the value of the receiver.
Now we can raise another difficulty. What if the variable storing the value being mutated is a read-only variable? Now what do we do? If you're curious, read my article on the subject and see if you can correctly answer the puzzle presented:
http://blogs.msdn.com/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx
The this keyword is a pointer to the current object. All non-static member functions of a class have access to a this pointer.
The pointer to the current object is normally made available by the compiler in a non-static member function by using a register, usually ECX. So when you write this in a non-static member function the compiler will translate that call into loading the address from ECX.
Check this simple example:
A t;
t.Test();
004114DE lea ecx,[t]
004114E1 call std::operator > (41125Dh)
Before calling the non-static member function Test() the compiler loads the register ECX with [t] (the address of variable t - will be this inside Test method).
004114DE lea ecx,[t]
And inside the function it can use ecx to obtain the address for the current object instance.
this is a hidden parameter in all methods of an object and contains a copy of the instance pointer.
Consider this class
class A {
private:
int data;
public:
void SetData(int arg) {
this->data = arg;
}
}
and this code that calls SetData():
A objA;
objA.SetData(1);
When the above code is compiled, the compiler emits something equivalent to this for the member function:
void SetData(A* this, int arg) {
this->data = arg;
}
And the calling code is converted to something like this:
A objA;
SetData(&objA, 1);
What this means is that upon compilation:
Member functions are converted to simple, global functions.
The class instance to which member functions "belong" is simply passed as the first argument to them (or rather its address is passed).
So in conclusion, what you refer to as this pointer in your code simply ends being the the first argument to the function. This is how the "system knows" which object to access through the "this" pointer.
The above example is of C++. If you for a moment forget about the CLR and the JITting and all that, what happens in C# is conceptually the same thing.
At run time "this" will resolve to the pointer to the current object, therefore "the system" will be able to call a respective method on that object.
I would have answered "It is a reference to the instance of the current class."
Dan
The compiler takes care of correctly resolving that reference at compile time. If you want to know more information about some of the techniques they use to do this, this book will tell you everything you need to know:
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
in c the this pointer is an invisible pointer argument to your class.
So in essence the first argument to a class method is the pointer to the class itself. You reference it by using this.
My answer would have been "Who cares? It knows. If I ever need to find out in more detail I'll Google it."
You obviously know what the effect of using "this" would be, which surely is the important thing. For 99% of programming tasks I would have thought that the detail of how it is resolved internally is trivia.
Shematicaly compiler converts such code:
pObject->someMethod(A,B,C)
Into such code if 'someMethod' is not virtual:
someMethod(pObject,A,B,C)
Or into such code if 'someMethod' is virtual:
(*pObject->vtable[someMethodIndex]) (pObject, A,B,C)
And everywhere you place 'this' keyword first parameter is used instead of it;
Of course compiler may optimize/simplify by removing first argument and use some CPU register (normally esx) to store object's address.
The "this" operator will point to the current object. An example where the presence of a "this" operator will make a difference is this:
public class MyClass
{
int value;
public void Test(int value)
{
MessageBox.Show(value); // Will show the parameter to the function
MessageBox.Show(this.value); // Will show the field in the object
}
}
Note that the "this" operator will not change what virtual function will be called if it is overridden in a child class
public class MyClass
{
public virtual void Test() {}
public void CallTest()
{
this.Test();
}
}
public class MyClass2 : MyClass
{
public override void Test() {}
}
If you execute the following code
MyClass c = new MyClass2();
c.CallTest();
will still call the MyClass2.Test() and not MyClass.Test()
So the "this" operator simply tells you, that you are accessing something declared at class level.