I have an object with 100 properties. Is there a feature in Resharper or Visual Studio 2017 that generates the code for all the properties of the object. e.g.
var myObject = new ObjectWithMultipleProps
{
Prop1 = "",
Prop2 = 0,
Prop3 = "",
...etch
}
I am creating unit tests and it would speed up things if this would be possible.
type this much:
var myObject = new ObjectWithMultipleProps {
Then press Ctrl+J, Tab. The next unused field or Property will get auto completed for you. You can press Ctrl+J again and it will pop up the type of the field so you can choose an appropriate value. Or you can start typing new then press Ctrl+J and it will auto-complete the type for you.
Then type a comma, and repeat the process for each field. Fields that you have already specified will not appear in the list. If you do not want to set a value for a field, then omit it from the initializer list, and it will get its default value.
You seem to have a misunderstanding on what creating an instance means. There´s no way for an instantiated object (this is when you called new ...) to have no value for any of your members. All those members are initialized from the runtime to the default-type for the type of that member. In particular you can´t partly initialize your object, that is set only some members to an initial-value, whilst not setting others. Creating an instance is an all-or-nothing-operation.
So if you simply write this:
var myObject = new ObjectWithMultipleProps();
all properties within myObject will have their defualt-value. You can even print them:
Console.WriteLine(myObject.Prop2); // this will print 0
You coul of course write all those assignments into the class´ constructor:
class ObjectWithMultipleProps
{
public ObjectWithMultipleProps()
{
Prop1 = null;
Prop2 = 0;
}
}
This however has the exact same effect.
What may happen anyway is, that you get a NullReferenceException. This is because all reference-types default to null, making any call to those members yield to that exception, as shown in the following code:
var a = myObject.Prop1.SubsString(0, 1);
As Prop1 is initialized to null once the instance is completely created, you get a NullReferenceException, because you can´t call any member on null.
If you want other default-values for your members, you have to create the constructor and set the values there.
Related
I'm writing a compare properties two objects of some class, for further listing differences.
Class oldObj, newObj;
//some initiation of above
Class classObject = new Class();
var objectKeys = classObject .GetType().GetProperties().ToList();
objectKeys.ForEach(key => {
var previousKeyValue = key.GetValue(oldObj);
var newKeyValue = key.GetValue(newObj);
if (!Equals) {...}
});
In special cases, newObj or oldObj can be nulls.
My problem is that, in such a case: key.GetValue(null) I'm getting CS0120 exception - "Non-static method requires a target".
Looking at PropertyInfo options (from metadata):
public object? GetValue(object? obj);
I assumed that it will be able to handle such a situation with object being null, with e.g. return null as its value.
Could you please explain if this is proper behaviour of this code, or I'm making something wrong to use null?
In such a case I would probably just before ForEach make some verification if objects are nulls and write separate compare code, handling this situation.
You are misunderstanding the nature of the parameter that is passed to GetValue().
When you pass in an object reference, it means that the reference is an instance property on an instance of an object. If you omit the object reference, you are telling the reflection api that you are trying to access a static member.
I am having two variables of type string and SelectListItem and trying to use them in my code where i found something weird and looking for a reason .
Scenario 1:
public class Test1
{
string x=""
void Assign(string x)
{
x="I am modified value";
}
public void myMethod()
{
Assign(x);
console.WriteLine(x) // output : ""
}
}
Scenario 2 :
public class Test2
{
void Assign(SelectListItem x)
{
x.Text="Modified Text";
x.Value="Modified Value";
}
public void myMethod()
{
var x = new SelectListItem()
x.Text="present Text";
x.Value="present Value";
Assign(x);
console.WriteLine(x) // output : Text:"Modified Text" & Value:"Modified Value"
}
}
You can see in scenario1 my output is "" even tough i assign x="I am modified value" inside a function before printing the o/p but where as in scenario2 i get output of modified value Text:"Modified Text" & Value:"Modified Value" .
I really cant find a reason here only i can think is in scenario2 we are passing instance . so , when we modify automatically the change gets effected but i'm not sure is it really reason behind that one and no clue about scenario1
Reference types are also passed by value. When you pass a reference type variable it's reference value is copied into the parameter. Assigning a new reference will just create a new instance and copy the new reference value into the variable.So, it won't affect the variable you passed.On the other hand you are modifying the properties of SelectListItem. It's not the same as assigning a new reference, in that case since both parameter and the variable refers to the same location, you are modifying the same object.
There is a name collision between your parameter and class field. If you wanna modify the class field use this.x = x. If that's not the case you can use ref modifier:
void Assign(ref string x)
{
x="I am modified value";
}
In the first you pass string. Here you immediately reassign the reference itself, causing a disconnection with the variable that passed it in. If you would have used the ref modifier, the re-assignment would be propagated to the passed in argument.
In the latter you pass an object and change that object's properties inside the method. However you are still doing these operations on the same object as the one that's passed in: both references point to the same object. That's why these changes are visible in both contexts.
I am working with a non static class and want to display the answer of the method to the console window.
When I change the method to static and call from Main() an error stating "Object reference not set to an instance of an object" appears.
http://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(EHNullReference);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true
Why can't you call a non-static method from a static method?
According to this article I need to create an instance of the object using the "new" keyword. My understanding is that you have to create an object for a class and not a method.
http://msdn.microsoft.com/en-us/library/ms173110.aspx
So, I created a new object but it does not return the result.
GetSingleAsset Foo = new GetSingleAsset();
Console.WriteLine(Foo);
The output just gives the name of the method.
How can I see the return value of this non static method?
public Asset GetSingleAsset()
{
var memberId = Oid.FromToken("Member:20", _context.MetaModel);
var query = new Query(memberId);
var nameAttribute = _context.MetaModel.GetAttributeDefinition("Member.Name");
var emailAttribute = _context.MetaModel.GetAttributeDefinition("Member.Email");
query.Selection.Add(nameAttribute);
query.Selection.Add(emailAttribute);
var result = _context.Services.Retrieve(query);
var member = result.Assets[0];
LogResult(member.Oid.Token,
GetValue(member.GetAttribute(nameAttribute).Value),
GetValue(member.GetAttribute(emailAttribute).Value));
return member;
}
You need to do this:
NameOfYourClass instanceOfClass = new NameOfYourClass();
Console.WriteLine(instanceOfClass.NameOfMethod());
The "answer of the method to the console window" - in this case, is an object - and if you attempt to Console.WriteLine() an object, you will only see the object type written out to the Console - not its values.
Yes, Robert is correct - GetSingleAsset() is a method, not a class - because it returns a value of 'Asset' type - a class's constructor will have no return - and Patrick is correct if you want to see (via Console output) what the return is from that particular method - if it wasn't an object.
However, since 'Asset' is an object itself, if you simply did a Console.WriteLine(Asset) it would show you what the type of Asset deviates from .. not its values. For example, "System.Collection.Asset" would be printed and not the values that you are interested in.
You will need to put a breakpoint in the code at the point of class instantiation and look through the Locals Window to see the values that type 'Asset' contains and print out exactly the values that you are interested in ... chances are what values you are actually interested in are contained within another object within the Asset class .. perhaps a for loop is in order here.
Looking at this Microsoft article How to: Write a Copy Constructor (C#) and also this Generic C# Copy Constructor, wouldn't it be best/safe to use a reference to the class instance than to use a plain copy of the instance ?
public class Myclass()
{
private int[] row;
public MyClass(ref MyClass #class)
{
for(int i = 0; i<#class.row.Length;i++)
{
this.row[i] = #class.row[i];
}
}
}
What ref actually means:
void Change(SomeClass instance)
{
instance = new SomeClass();
}
void ChangeRef(ref SomeClass instance)
{
instance = new SomeClass();
}
Later...
SomeClass instance = new SomeClass();
Change(instance);
//value of instance remains unchanged here
ChangeRef(ref instance);
//at this line, instance has been changed to a new instance because
//ref keyword imports the `instance` variable from the call-site's scope
I can't see how this functionality would be useful with respect to a copy constructor.
Object by nature is reference not a value type. I do not see any good reason what extra advantage you would get doing it. But yes you might get into problems because of it, consider this -
You created an object and passed it with reference to couple of classes and those classes are now having access to the address of reference itself. Now I have got all the powers to go and change the reference itself with another object's reference. If here, another class had this object it is actually working on some stale object and other classes can not see what changes are being made and you are in chaos.
I do not see any use of doing it, rather it is dangerous. It does not sounds like a OO way of writing code to me.
The ref keyword is used when a method should be allowed to change the location of a reference. Reference types always pass their reference into a method (but the location of the reference cannot be modified via assignment). Values types pass their value.
See: Passing Parameters
Example:
void PassingByReference(List<int> collection)
{
// Compile error since method cannot change reference location
// collection = new List<int>();
collection.Add(1);
}
void ChangingAReference(ref List<int> collection)
{
// Allow to change location of collection with ref keyword
collection = new List<int>();
collection.Add(2);
}
var collection = new List<int>{ 5 };
// Pass the reference of collection to PassByReference
PassingByReference(collection);
// collection new contains 1
collection.Contains(5); // true
collection.Contains(1); // true
// Copy the reference of collection to another variable
var tempCollection = collection;
// Change the location of collection via ref keyword
ChangingAReference(ref collection);
// it is not the same collection anymore
collection.Contains(5); // false
collection.Contains(1); // false
// compare the references use the default == operator
var sameCollection = collection == tempCollection; // false
Can I somehow get a reference to the instance I am creating using object initialiser
var x = new TestClass
{
Id = 1,
SomeProperty = SomeMethod(this)
}
"this" should point to the new TestClass instance I'm creating. But it obviously refers the the instance of the class in which this code resides.
I'm not asking if this is a good way to do this.
I'm aware that I can do this like this:
var x = new TestClass {Id= x};
x.SomeProperty = SomeMethod(this);
I have a complicated scenario, in which a reference to the new instance in the object initialiser would make life easier.
Is this possible in any way?
There's no way around it, the C# specification explicitly says that "It is not possible for an object or collection initializer to refer to the object instance being initialized."
As for why it's impossible, I suspect that there's just no nice way to implement it. We want some syntactic sugar equivalent to
var temp = new TestClass();
temp.Id = 1;
temp.SomeProperty = SomeMethod(temp);
x = temp;
We just need a keyword to refer to temp within the initializer, but none is easily available. We can't use this because it already means something outside the initializer. Should SomeProperty = this.SomeMethod(this) be equivalent to temp.SomeProperty = this.SomeMethod(temp) or temp.SomeProperty = temp.SomeMethod(temp)? The second is consistent, but then what happens if we need the first?
We could try to use x, though we can only pick a name if the new object is immediately assigned to a variable. However, we now can't refer to the old value of x inside the initializer, doing the equivalent of temp.SomeProperty = SomeMethod(x).
We could reuse the value keyword from property setters. This sounds good since value already stands in for the missing parameter if you consider a property getter to be syntactic sugar for a set_SomeProperty(value) method. Using it to also refer to the missing variable in the object initializer looks promising. However, we could be creating this object inside a property setter, in which case value is already being used, and we need to be able to do temp.SomeProperty = SomeMethod(value).
It looks like we'll have to create a new keyword just for this purpose, maybe newthis. However, this is a breaking change to the language because any code that has a variable called newthis doesn't work any more. Microsoft generally needs a really good reason to introduce breaking changes, so it's better to forbid access to the object being initialized.
No, you can't use the object initializer to assign the object you're creating somewhere else - that defeats the whole point of the object initializer. The x variable doesn't get assigned until after the object initializer is completed. You'll need to assign the object, then use it in a separate statement.
var x = new TestClass {
Id = 1
};
x.SomeProperty = SomeMethod(x);
Exposing or using an object that hasn't been fully constructed is usually a very bad idea. Consider the following:
class Connection
{
internal string connectionString;
public Connection(ConnectionPool pool, string connectionString) {
this.pool = pool;
//this.connectionString = connectionString; // I moved it because I could.
this.pool.Register(this);
this.connectionString = connectionString;
this.Init();
}
private void Init() { //blah }
}
class ConnectionPool
{
public void Register(Connection c)
{
if ( this.connStrings.Contains( c.connectionString ) ) // BOOM
}
}
This is an extremely contrived example. Things can get a whole lot worse than this. The following was quite an interesting link regarding this issue:
Partially Constructed Objects
var x = new TestClass
{
Id = 1,
SomeProperty = SomeMethod(this)
}
Before the right part of this initialization is evaluated and executed, the reference to the new object is not yet made available to the code. That is done for security purposes, otherwise you could create some deadlock or endless loop with you code.