This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Initializer syntax
Short code sample to demonstrate (VS2010 SP1, 64-bit Win7):
class A
{
public string Name { get; set; }
}
class B
{
public A a { get; set; }
}
// OK
A a = new A { Name = "foo" };
// Using collection initialiser syntax fails as expected:
// "Can only use array initializer expressions to assign
// to array types. Try using a new expression instead."
A a = { Name = "foo" };
// OK
B b = new B { a = new A { Name = "foo" } };
// Compiles, but throws NullReferenceException when run
B b = new B { a = { Name = "foo" } };
I was surprised to see that last line compile and thought I'd found a nifty (though inconsistent) shortcut before seeing it blow up at runtime. Does that last usage have any utility?
The last line is translated to:
B tmp = new B();
tmp.a.Name = "foo";
B b = tmp;
And yes, it very definitely has utility - when the newly created object has a read-only property returning a mutable type. The most common use of something similar is probably for collections though:
Person person = new Person {
Friends = {
new Person("Dave"),
new Person("Bob"),
}
}
This will fetch the list of friends from Person and add two new people to it.
Related
I recently encountered a nice feature in C#. I don't know its name, but somehow it'll free us from typing new ClassName() thing. Which means the following snippet:
var myObject = new MyObjectClass
{
MyProperty = new MyPropertyClass
{
StrValue = "Foo"
}
}
Could be changed to:
var myObject = new MyObjectClass
{
MyProperty =
{
StrValue = "Foo"
}
}
There is no new MyPropertyClass anymore right?
BTW: I'm using C# 8.0.
Question: What is this feature's name? Although the details could be googled knowing the feature's name, but it would be nice if someone has a brief overview.
It looks like you mean Target-typed new expressions. This feature allows omitting type specification for constructors when the type is known or when it can be inferred from usage.
The feature will be in C# 9.0 which is part of the .NET 5 development platform. The scheduled release time is November 2020.
The new syntax will look like:
public class Person
{
public Vehicle Vehicle { get; set; }
}
public class Vehicle
{
public string Name { get; set; }
}
var person = new Person()
{
Vehicle = new ()
{
Name = "Car"
}
};
This question already has an answer here:
Nested object initializer syntax
(1 answer)
Closed 4 years ago.
Whille creating some dummy data for a collection for a WPF/MVVM project, I produced the following wrong code, which compiles fine, but throws an exception at runtime.
There's a nested structure of data objects, which I wrongly instantiate with only the curly braces (looks like writing JavaScript does cause permanent damage to the brain).
using System.Collections.ObjectModel;
namespace testapp
{
class Program
{
static void Main(string[] args)
{
var collection = new ObservableCollection<TopLevelDataObject>();
collection.Add(new TopLevelDataObject{Nested = {Bar = 5}}); // NullReferenceException
}
class TopLevelDataObject
{
public NestedDataObject Nested { get; set; }
public string Foo { get; set; }
}
class NestedDataObject
{
public double Bar { get; set; }
}
}
}
Why does that compile?
If I create an annonymous type, like Nested = new {Bar = 5}, I get the error message during compilation (which thus fails):
Cannot implicitly convert type '<anonymous type: int Bar>' to 'testapp.Program.NestedDataObject'
Why do I not get such an error when ommitting the new operator?
It even gives me a code hint for the property:
My guess would be that {Bar = 5} is simply a code block, which on its own is a valid thing to have.
But why is it valid to assign a code block to anything (in this case, the Nested property)?
Why does that compile?
Because when that code is compiled, it is compiled as just a set of assignment operations. It doesn't all have to be new instances you create.
If you construct a new instance of Nested from the constructor, you can assign a value to Nested.Bar.
Change public NestedDataObject Nested { get; set; } to this to see how it works:
public NestedDataObject Nested { get; } = new NestedDataObject();
(Note you can never assign a value to Nested outside the constructor in the above code!)
Why does that compile?
Because var x = new SomeType{Property = value}; is the same as:
var x = new SomeType();
x.Property = value;
Indeed we can even leave in the () to have var x = new SomeType(){Property = value}; or even var x = new SomeType(argument){Property = value}; combining passing an argument to the constructor and setting a value.
As such you can see that there is always a constructor called, and if you leave out the parentheses that make that explicit its always the nullary (no-argument) constructor.
Meanwhile a type with no explicit constructor always has a public nullary constructor (the "default constructor").
Hence new TopLevelDataObject{Nested = {Bar = 5}} is the same as:
var temp = new TopLevelDataObject();
temp.Nested.Bar = 5; // NRE on temp.Nested
Because TopLevelDataObject could have a constructor that sets `Nestedt then the code you have could work, so it should compile. Of course, because it doesn't have such a constructor it doesn't work.
(Note that initialisers don't operate quite the same with anonymous types, in that case it gets rewritten to call a hidden constructor hence allowing the properties to be read-only even though initialisers cannot be used with read-only properties of non-anonymous types. The syntax allows them to look the same and hence be easily understood as similar but the result is not the same).
This question already has answers here:
Why are C# 3.0 object initializer constructor parentheses optional?
(5 answers)
Closed 7 years ago.
When initializing a new List in C#, both of following will compile:
(1) List<string> s = new List<string>() { "value" };
and
(2) List<string> s = new List<string> { "value" };
What is the difference between case 1 and case 2?
This rings true for any type. Generally, you specify the () if you need to pass something to the types constructor that it doesn't expose for setting publically. If there's no parameters needed, the () are just fluff.
Consider the scenario that you may want to do some additional validation/logic to a property and you don't allow direct manipulation of it:
public class Foo
{
private string Bar { get; set; }
public string FooBar { get; set; }
public Foo (string bar)
{
Bar = bar + "foo";
}
}
So this is allowed:
var foo = new Foo("bar")
{
FooBar = "foobar"
};
Yet this isn't:
var foo = new Foo
{
Bar = "bar",
FooBar = "foobar"
};
There are some C# types that only allow you to set certain properties within the constructor.
There is no difference. It will be translated as:
List<string> s1 = new List<string>();
s1.Add("value");
List<string> s2 = new List<string>();
s2.Add("value");
From 7.6.10.1 Object creation expressions of the C# reference 5.0:
An object creation expression can omit the constructor argument list and enclosing parentheses provided it includes an object initializer or collection initializer. Omitting the constructor argument list and enclosing parentheses is equivalent to specifying an empty argument list.
The latter is called Object Initialization. You may also use MyClass m = new MyClass { MyVar = 3 };
My application uses a list like this:
List<MyClass> list = new List<MyClass>();
Using the Add method, another instance of MyClass is added to the list.
MyClass provides, among others, the following methods:
public void SetId(String Id);
public String GetId();
How can I find a specific instance of MyClass by means of using the GetId method? I know there is the Find method, but I don't know if this would work here?!
Use a lambda expression
MyClass result = list.Find(x => x.GetId() == "xy");
Note: C# has a built-in syntax for properties. Instead of writing getter and setter as ordinary methods (as you might be used to from Java), write
private string _id;
public string Id
{
get
{
return _id;
}
set
{
_id = value;
}
}
value is a contextual keyword known only in the set accessor. It represents the value assigned to the property.
Since this pattern is often used, C# provides auto-implemented properties. They are a short version of the code above; however, the backing variable is hidden and not accessible (it is accessible from within the class in VB, however).
public string Id { get; set; }
You can simply use properties as if you were accessing a field:
var obj = new MyClass();
obj.Id = "xy"; // Calls the setter with "xy" assigned to the value parameter.
string id = obj.Id; // Calls the getter.
Using properties, you would search for items in the list like this
MyClass result = list.Find(x => x.Id == "xy");
You can also use auto-implemented properties if you need a read-only property:
public string Id { get; private set; }
This enables you to set the Id within the class but not from outside. If you need to set it in derived classes as well you can also protect the setter
public string Id { get; protected set; }
And finally, you can declare properties as virtual and override them in deriving classes, allowing you to provide different implementations for getters and setters; just as for ordinary virtual methods.
Since C# 6.0 (Visual Studio 2015, Roslyn) you can write getter-only auto-properties with an inline initializer
public string Id { get; } = "A07"; // Evaluated once when object is initialized.
You can also initialize getter-only properties within the constructor instead. Getter-only auto-properties are true read-only properties, unlike auto-implemented properties with a private setter.
This works also with read-write auto-properties:
public string Id { get; set; } = "A07";
Beginning with C# 6.0 you can also write properties as expression-bodied members
public DateTime Yesterday => DateTime.Date.AddDays(-1); // Evaluated at each call.
// Instead of
public DateTime Yesterday { get { return DateTime.Date.AddDays(-1); } }
See: .NET Compiler Platform ("Roslyn")
New Language Features in C# 6
Starting with C# 7.0, both, getter and setter, can be written with expression bodies:
public string Name
{
get => _name; // getter
set => _name = value; // setter
}
Note that in this case the setter must be an expression. It cannot be a statement. The example above works, because in C# an assignment can be used as an expression or as a statement. The value of an assignment expression is the assigned value where the assignment itself is a side effect. This allows you to assign a value to more than one variable at once: x = y = z = 0 is equivalent to x = (y = (z = 0)) and has the same effect as the statements z = 0; y = 0; x = 0;.
Since C# 9.0 you can use read-only (or better initialize-once) properties that you can initialize in an object initializer. This is currently not possible with getter-only properties.
public string Name { get; init; }
var c = new C { Name = "c-sharp" };
Beginning with C# 11, you can have a required property to force client code to initialize it.
The field keyword is planned for a future version of C# (it did not make it into C# 11) and allows the access to the automatically created backing field.
// Removes time part in setter
public DateTime HiredDate { get; init => field = value.Date(); }
public Data LazyData => field ??= new Data();
var list = new List<MyClass>();
var item = list.Find( x => x.GetId() == "TARGET_ID" );
or if there is only one and you want to enforce that something like SingleOrDefault may be what you want
var item = list.SingleOrDefault( x => x.GetId() == "TARGET" );
if ( item == null )
throw new Exception();
Try:
list.Find(item => item.id==myid);
Or if you do not prefer to use LINQ you can do it the old-school way:
List<MyClass> list = new List<MyClass>();
foreach (MyClass element in list)
{
if (element.GetId() == "heres_where_you_put_what_you_are_looking_for")
{
break; // If you only want to find the first instance a break here would be best for your application
}
}
You can also use LINQ extensions:
string id = "hello";
MyClass result = list.Where(m => m.GetId() == id).First();
You can solve your problem most concisely with a predicate written using anonymous method syntax:
MyClass found = list.Find(item => item.GetID() == ID);
public List<DealsCategory> DealCategory { get; set; }
int categoryid = Convert.ToInt16(dealsModel.DealCategory.Select(x => x.Id));
You can create a search variable to hold your searching criteria. Here is an example using database.
var query = from o in this.mJDBDataset.Products
where o.ProductStatus == textBox1.Text || o.Karrot == textBox1.Text
|| o.ProductDetails == textBox1.Text || o.DepositDate == textBox1.Text
|| o.SellDate == textBox1.Text
select o;
dataGridView1.DataSource = query.ToList();
//Search and Calculate
search = textBox1.Text;
cnn.Open();
string query1 = string.Format("select * from Products where ProductStatus='"
+ search +"'");
SqlDataAdapter da = new SqlDataAdapter(query1, cnn);
DataSet ds = new DataSet();
da.Fill(ds, "Products");
SqlDataReader reader;
reader = new SqlCommand(query1, cnn).ExecuteReader();
List<double> DuePayment = new List<double>();
if (reader.HasRows)
{
while (reader.Read())
{
foreach (DataRow row in ds.Tables["Products"].Rows)
{
DuePaymentstring.Add(row["DuePayment"].ToString());
DuePayment = DuePaymentstring.Select(x => double.Parse(x)).ToList();
}
}
tdp = 0;
tdp = DuePayment.Sum();
DuePaymentstring.Remove(Convert.ToString(DuePaymentstring.Count));
DuePayment.Clear();
}
cnn.Close();
label3.Text = Convert.ToString(tdp + " Due Payment Count: " +
DuePayment.Count + " Due Payment string Count: " + DuePaymentstring.Count);
tdp = 0;
//DuePaymentstring.RemoveRange(0,DuePaymentstring.Count);
//DuePayment.RemoveRange(0, DuePayment.Count);
//Search and Calculate
Here "var query" is generating the search criteria you are giving through the search variable. Then "DuePaymentstring.Select" is selecting the data matching your given criteria. Feel free to ask if you have problem understanding.
This might be lame, but here:
public interface Interface<T>
{
T Value { get; }
}
public class InterfaceProxy<T> : Interface<T>
{
public T Value { get; set; }
}
public class ImplementedInterface: InterfaceProxy<Double> {}
Now I want to create an instance of the ImplementedInterface and initialize it's members.
Can this be done somehow like this (using initialization lists) or the same behavior can only be achieved using the constructor with Double argument?
var x = new ImplementedInteface { 30.0 };
Can be done by:
var x = new ImplementedInteface { Value = 30.0 };
var x = new ImplementedInterface() { Value = 30.0 };
The only way to achieve what you're after is if your class implements IEnumerable<T> and has an Add method:
public class MyClass : IEnumerable<double>
{
public void Add(double x){}
}
Then you can do:
MyClass mc = new MyClass { 20.0 };
Obviously that's not what you want, because that doesn't set your Value and it allows you to add multiple values:
MyClass mc = new MyClass { 20.0, 30.0 , 40.0 };
Just go with the standard object initializes like others have pointed out:
var x = new ImplementedInterface() { Value = 30.0 };
You should be able to do:
var x = new ImplementedInterface {Value = 30.0};
var instance = new ImplementedInterface { Value = 30.0 }; will work. However, this isn't really the same set of operations as C++ initializer lists -- this is an object initializer. It initializes the new instance via the default constructor and then invokes the property setters for each property.
In other words, the object is constructed before the property setters run. If you want the values for the properties set before construction of ImplementedInterface completes, you'd have to write a constructor, as you noted. This distinction in behavior usually doesn't matter, but it's good to be aware of.
I am not sure if you have a special reason to use the interfaces that way but the following code might work for you.
public class ImplementedInterface2 : List<double> { }
public class test
{
public void x()
{
var x = new ImplementedInterface2() { 30.0 };
}
}
var x = new ImplementedInterface { Value = 30.0 };
You can definitely use an initialization list, but you have to specify what 30.0 is (this is true for any initialization list, not just the code you have):
var x = new ImplementedInteface { Value=30.0 };