About 3/4 down the page in the "Using Objects" section:
VB:
With hero
.Name = "SpamMan"
.PowerLevel = 3
End With
C#:
//No "With" construct
hero.Name = "SpamMan";
hero.PowerLevel = 3;
Sometimes you can get away with doing the following:
var fill = cell.Style.Fill;
fill.PatternType = ExcelFillStyle.Solid;
fill.BackgroundColor.SetColor(Color.Gray);
fill.PatternColor = Color.Black;
fill.Gradient = ...
(Code sample for EPPLus @ http://zeeshanumardotnet.blogspot.com)
You could use the argument accumulator pattern.
Big discussion about this here:
http://blogs.msdn.com/csharpfaq/archive/2004/03/11/87817.aspx
A big fan of With
here!
This is literally my current C# code:
if (SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.AccessTokenExpiry == null || SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.AccessTokenExpiry < DateTime.Now)
{
SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.Refresh();
_api = new SKYLib.AccountsPayable.Api.DefaultApi(new SKYLib.AccountsPayable.Client.Configuration { DefaultHeader = SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.ApiHeader });
}
In VB it could be:
With SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization
If .AccessTokenExpiry Is Nothing OrElse .AccessTokenExpiry < Now Then .Refresh()
_api = New SKYLib.AccountsPayable.Api.DefaultApi(New SKYLib.AccountsPayable.Client.Configuration With {DefaultHeader = .ApiHeaders}
End With
Much clearer I think. You could even tweak it to be more concise by tuning the With
variable. And, style-wise, I still have a choice! Perhaps something the C# Program Manager has overlooked.
As an aside, it's not very common to see this, but I have used it on occasion:
Instead of
Using oClient As HttpClient = New HttpClient
With oClient
.BaseAddress = New Uri("http://mysite")
.Timeout = New TimeSpan(123)
.PostAsync( ... )
End With
End Using
You can use
With New HttpClient
.BaseAddress = New Uri("http://mysite")
.Timeout = New TimeSpan(123)
.PostAsync( ... )
End With
You risk a wrist-slapping - as do I for posting! - but it seems that you get all the benefits of a Using
statement in terms of disposal, etc without the extra rigmarole.
NOTE: This can go wrong occasionally, so only use it for non-critical code. Or not at all. Remember: You have a choice ...
Although C# doesn't have any direct equivalent for the general case, C# 3 gain object initializer syntax for constructor calls:
var foo = new Foo { Property1 = value1, Property2 = value2, etc };
See chapter 8 of C# in Depth for more details - you can download it for free from Manning's web site.
(Disclaimer - yes, it's in my interest to get the book into more people's hands. But hey, it's a free chapter which gives you more information on a related topic...)
About 3/4 down the page in the "Using Objects" section:
VB:
With hero
.Name = "SpamMan"
.PowerLevel = 3
End With
C#:
//No "With" construct
hero.Name = "SpamMan";
hero.PowerLevel = 3;
For me I was trying to auto generate code, and needed to reuse a simple variable like "x" for multiple different classes so that I didn't have to keep generating new variable names. I found that I could limit the scope of a variable and reuse it multiple times if I just put the code in a curly brace section {}.
See the example:
public class Main
{
public void Execute()
{
// Execute new Foos and new Bars many times with same variable.
double a = 0;
double b = 0;
double c = 0;
double d = 0;
double e = 0;
double f = 0;
double length = 0;
double area = 0;
double size = 0;
{
Foo x = new Foo(5, 6).Execute();
a = x.A;
b = x.B;
c = x.C;
d = x.D;
e = x.E;
f = x.F;
}
{
Bar x = new Bar("red", "circle").Execute();
length = x.Length;
area = x.Area;
size = x.Size;
}
{
Foo x = new Foo(3, 10).Execute();
a = x.A;
b = x.B;
c = x.C;
d = x.D;
e = x.E;
f = x.F;
}
{
Bar x = new Bar("blue", "square").Execute();
length = x.Length;
area = x.Area;
size = x.Size;
}
}
}
public class Foo
{
public int X { get; set; }
public int Y { get; set; }
public double A { get; private set; }
public double B { get; private set; }
public double C { get; private set; }
public double D { get; private set; }
public double E { get; private set; }
public double F { get; private set; }
public Foo(int x, int y)
{
X = x;
Y = y;
}
public Foo Execute()
{
A = X * Y;
B = X + Y;
C = X / (X + Y + 1);
D = Y / (X + Y + 1);
E = (X + Y) / (X + Y + 1);
F = (Y - X) / (X + Y + 1);
return this;
}
}
public class Bar
{
public string Color { get; set; }
public string Shape { get; set; }
public double Size { get; private set; }
public double Area { get; private set; }
public double Length { get; private set; }
public Bar(string color, string shape)
{
Color = color;
Shape = shape;
}
public Bar Execute()
{
Length = Color.Length + Shape.Length;
Area = Color.Length * Shape.Length;
Size = Area * Length;
return this;
}
}
In VB I would have used the With and not needed variable "x" at all. Excluding the vb class definitions of Foo and Bar, the vb code is:
Public Class Main
Public Sub Execute()
Dim a As Double = 0
Dim b As Double = 0
Dim c As Double = 0
Dim d As Double = 0
Dim e As Double = 0
Dim f As Double = 0
Dim length As Double = 0
Dim area As Double = 0
Dim size As Double = 0
With New Foo(5, 6).Execute()
a = .A
b = .B
c = .C
d = .D
e = .E
f = .F
End With
With New Bar("red", "circle").Execute()
length = .Length
area = .Area
size = .Size
End With
With New Foo(3, 10).Execute()
a = .A
b = .B
c = .C
d = .D
e = .E
f = .F
End With
With New Bar("blue", "square").Execute()
length = .Length
area = .Area
size = .Size
End With
End Sub
End Class
You could use the argument accumulator pattern.
Big discussion about this here:
http://blogs.msdn.com/csharpfaq/archive/2004/03/11/87817.aspx
Although C# doesn't have any direct equivalent for the general case, C# 3 gain object initializer syntax for constructor calls:
var foo = new Foo { Property1 = value1, Property2 = value2, etc };
See chapter 8 of C# in Depth for more details - you can download it for free from Manning's web site.
(Disclaimer - yes, it's in my interest to get the book into more people's hands. But hey, it's a free chapter which gives you more information on a related topic...)
What I do is use a csharp ref keyword. For example:
ref MySubClassType e = ref MyMainClass.MySubClass;
you can then use the shortcut like:
e.property
instead of MyMainClass.MySubClass.property
I think the closets thing to "with" is static using
, but only works with static's methods or properties.
e.g.
using static System.Math;
...
public double Area
{
get { return PI * Pow(Radius, 2); } // PI == System.Math.PI
}
More Info: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static
There is another an interesting implementation of with-pattern
public static T With<T>(this T o, params object[] pattern) => o;
public static T To<T>(this T o, out T x) => x = o;
You may browse more details by the link and research online code samples.
Variations of usage
static Point Sample0() => new Point().To(out var p).With(
p.X = 123,
p.Y = 321,
p.Name = "abc"
);
public static Point GetPoint() => new Point { Name = "Point Name" };
static string NameProperty { get; set; }
static string NameField;
static void Sample1()
{
string nameLocal;
GetPoint().To(out var p).With(
p.X = 123,
p.Y = 321,
p.Name.To(out var name), /* right side assignment to the new variable */
p.Name.To(out nameLocal), /* right side assignment to the declared var */
NameField = p.Name, /* left side assignment to the declared variable */
NameProperty = p.Name /* left side assignment to the property */
);
Console.WriteLine(name);
Console.WriteLine(nameLocal);
Console.WriteLine(NameField);
Console.WriteLine(NameProperty);
}
static void Sample2() /* non-null propogation sample */
{
((Point)null).To(out var p)?.With(
p.X = 123,
p.Y = 321,
p.Name.To(out var name)
);
Console.WriteLine("No exception");
}
static void Sample3() /* recursion */
{
GetPerson().To(out var p).With(
p.Name.To(out var name),
p.Subperson.To(out var p0).With(
p0.Name.To(out var subpersonName0)
),
p.GetSubperson().To(out var p1).With( /* method return */
p1.Name.To(out var subpersonName1)
)
);
Console.WriteLine(subpersonName0);
Console.WriteLine(subpersonName1);
}
If you work with structs [value types] the similar extension method will be useful too
public static TR Let<T, TR>(this T o, TR y) => y;
May be applied after With method because by default will be returned the unmodified copy of struct
struct Point
{
public double X;
public double Y;
public string Name;
}
static Point Sample0() => new Point().To(out var p).With(
p.X = 123,
p.Y = 321,
p.Name = "abc"
).Let(p);
Enjoy if you like!
To make life a little easier you can use vertical selection to quickly edit things
http://joelabrahamsson.com/select-columns-of-text-in-visual-studio/
About 3/4 down the page in the "Using Objects" section:
VB:
With hero
.Name = "SpamMan"
.PowerLevel = 3
End With
C#:
//No "With" construct
hero.Name = "SpamMan";
hero.PowerLevel = 3;
You could use the argument accumulator pattern.
Big discussion about this here:
http://blogs.msdn.com/csharpfaq/archive/2004/03/11/87817.aspx
Although C# doesn't have any direct equivalent for the general case, C# 3 gain object initializer syntax for constructor calls:
var foo = new Foo { Property1 = value1, Property2 = value2, etc };
See chapter 8 of C# in Depth for more details - you can download it for free from Manning's web site.
(Disclaimer - yes, it's in my interest to get the book into more people's hands. But hey, it's a free chapter which gives you more information on a related topic...)
You could use the argument accumulator pattern.
Big discussion about this here:
http://blogs.msdn.com/csharpfaq/archive/2004/03/11/87817.aspx
The with
keywork is introduced in C# version 9!
you can use it to create copy of object like follows
Person brother = person with { FirstName = "Paul" };
"The above line creates a new Person record where the LastName property is a copy of person, and the FirstName is "Paul". You can set any number of properties in a with-expression. Any of the synthesized members except the "clone" method may be written by you. If a record type has a method that matches the signature of any synthesized method, the compiler doesn't synthesize that method."
UPDATE:
At the time this answer is written, C#9 is not officially released but in preview only. However, it is planned to be shipped along with .NET 5.0 in November 2020
for more information, check the record types.
I was using this way:
worksheet.get_Range(11, 1, 11, 41)
.SetHeadFontStyle()
.SetHeadFillStyle(45)
.SetBorders(
XlBorderWeight.xlMedium
, XlBorderWeight.xlThick
, XlBorderWeight.xlMedium
, XlBorderWeight.xlThick)
;
SetHeadFontStyle / SetHeadFillStyle is ExtMethod of Range like below:
public static Range SetHeadFillStyle(this Range rng, int colorIndex)
{
//do some operation
return rng;
}
do some operation and return the Range for next operation
it's look like Linq :)
but now still can't fully look like it -- propery set value
with cell.Border(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlMedium
.ColorIndex = xlAutomatic
There is another an interesting implementation of with-pattern
public static T With<T>(this T o, params object[] pattern) => o;
public static T To<T>(this T o, out T x) => x = o;
You may browse more details by the link and research online code samples.
Variations of usage
static Point Sample0() => new Point().To(out var p).With(
p.X = 123,
p.Y = 321,
p.Name = "abc"
);
public static Point GetPoint() => new Point { Name = "Point Name" };
static string NameProperty { get; set; }
static string NameField;
static void Sample1()
{
string nameLocal;
GetPoint().To(out var p).With(
p.X = 123,
p.Y = 321,
p.Name.To(out var name), /* right side assignment to the new variable */
p.Name.To(out nameLocal), /* right side assignment to the declared var */
NameField = p.Name, /* left side assignment to the declared variable */
NameProperty = p.Name /* left side assignment to the property */
);
Console.WriteLine(name);
Console.WriteLine(nameLocal);
Console.WriteLine(NameField);
Console.WriteLine(NameProperty);
}
static void Sample2() /* non-null propogation sample */
{
((Point)null).To(out var p)?.With(
p.X = 123,
p.Y = 321,
p.Name.To(out var name)
);
Console.WriteLine("No exception");
}
static void Sample3() /* recursion */
{
GetPerson().To(out var p).With(
p.Name.To(out var name),
p.Subperson.To(out var p0).With(
p0.Name.To(out var subpersonName0)
),
p.GetSubperson().To(out var p1).With( /* method return */
p1.Name.To(out var subpersonName1)
)
);
Console.WriteLine(subpersonName0);
Console.WriteLine(subpersonName1);
}
If you work with structs [value types] the similar extension method will be useful too
public static TR Let<T, TR>(this T o, TR y) => y;
May be applied after With method because by default will be returned the unmodified copy of struct
struct Point
{
public double X;
public double Y;
public string Name;
}
static Point Sample0() => new Point().To(out var p).With(
p.X = 123,
p.Y = 321,
p.Name = "abc"
).Let(p);
Enjoy if you like!
If there are multiple levels of objects you can get similar functionality with the "using" directive:
using System;
using GenderType = Hero.GenderType; //This is the shorthand using directive
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var myHero = new Hero();
myHero.Name = "SpamMan";
myHero.PowerLevel = 3;
myHero.Gender = GenderType.Male; //instead of myHero.Gender = Hero.GenderType.Male;
}
}
public class Hero
{
public enum GenderType
{
Male,
Female,
Other
}
public string Name;
public int PowerLevel;
public GenderType Gender;
}
hmm. I have never used VB.net in any depth, so I'm making an assumption here, but I think the 'using' block might be close to what you want.
using defines a block scope for a variable, see the example below
using ( int temp = someFunction(param1) ) {
temp++; // this works fine
}
temp++; // this blows up as temp is out of scope here and has been disposed
Here is an article from Microsoft that explains a bit more
EDIT: yeah, this answer is wrong - the original assumption was incorrect. VB's 'WITH' is more like the new C# object initialisers:
var yourVariable = new yourObject { param1 = 20, param2 = "some string" };
I was using this way:
worksheet.get_Range(11, 1, 11, 41)
.SetHeadFontStyle()
.SetHeadFillStyle(45)
.SetBorders(
XlBorderWeight.xlMedium
, XlBorderWeight.xlThick
, XlBorderWeight.xlMedium
, XlBorderWeight.xlThick)
;
SetHeadFontStyle / SetHeadFillStyle is ExtMethod of Range like below:
public static Range SetHeadFillStyle(this Range rng, int colorIndex)
{
//do some operation
return rng;
}
do some operation and return the Range for next operation
it's look like Linq :)
but now still can't fully look like it -- propery set value
with cell.Border(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlMedium
.ColorIndex = xlAutomatic
hmm. I have never used VB.net in any depth, so I'm making an assumption here, but I think the 'using' block might be close to what you want.
using defines a block scope for a variable, see the example below
using ( int temp = someFunction(param1) ) {
temp++; // this works fine
}
temp++; // this blows up as temp is out of scope here and has been disposed
Here is an article from Microsoft that explains a bit more
EDIT: yeah, this answer is wrong - the original assumption was incorrect. VB's 'WITH' is more like the new C# object initialisers:
var yourVariable = new yourObject { param1 = 20, param2 = "some string" };
No, there is not.
I think the closets thing to "with" is static using
, but only works with static's methods or properties.
e.g.
using static System.Math;
...
public double Area
{
get { return PI * Pow(Radius, 2); } // PI == System.Math.PI
}
More Info: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static
Most simple syntax would be:
{
var where = new MyObject();
where.property = "xxx";
where.SomeFunction("yyy");
}
{
var where = new MyObject();
where.property = "zzz";
where.SomeFunction("uuu");
}
Actually extra code-blocks like that are very handy if you want to re-use variable names.
If there are multiple levels of objects you can get similar functionality with the "using" directive:
using System;
using GenderType = Hero.GenderType; //This is the shorthand using directive
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var myHero = new Hero();
myHero.Name = "SpamMan";
myHero.PowerLevel = 3;
myHero.Gender = GenderType.Male; //instead of myHero.Gender = Hero.GenderType.Male;
}
}
public class Hero
{
public enum GenderType
{
Male,
Female,
Other
}
public string Name;
public int PowerLevel;
public GenderType Gender;
}
Although C# doesn't have any direct equivalent for the general case, C# 3 gain object initializer syntax for constructor calls:
var foo = new Foo { Property1 = value1, Property2 = value2, etc };
See chapter 8 of C# in Depth for more details - you can download it for free from Manning's web site.
(Disclaimer - yes, it's in my interest to get the book into more people's hands. But hey, it's a free chapter which gives you more information on a related topic...)
About 3/4 down the page in the "Using Objects" section:
VB:
With hero
.Name = "SpamMan"
.PowerLevel = 3
End With
C#:
//No "With" construct
hero.Name = "SpamMan";
hero.PowerLevel = 3;
hmm. I have never used VB.net in any depth, so I'm making an assumption here, but I think the 'using' block might be close to what you want.
using defines a block scope for a variable, see the example below
using ( int temp = someFunction(param1) ) {
temp++; // this works fine
}
temp++; // this blows up as temp is out of scope here and has been disposed
Here is an article from Microsoft that explains a bit more
EDIT: yeah, this answer is wrong - the original assumption was incorrect. VB's 'WITH' is more like the new C# object initialisers:
var yourVariable = new yourObject { param1 = 20, param2 = "some string" };
What I do is use a csharp ref keyword. For example:
ref MySubClassType e = ref MyMainClass.MySubClass;
you can then use the shortcut like:
e.property
instead of MyMainClass.MySubClass.property
Most simple syntax would be:
{
var where = new MyObject();
where.property = "xxx";
where.SomeFunction("yyy");
}
{
var where = new MyObject();
where.property = "zzz";
where.SomeFunction("uuu");
}
Actually extra code-blocks like that are very handy if you want to re-use variable names.
No, there is not.
Sometimes you can get away with doing the following:
var fill = cell.Style.Fill;
fill.PatternType = ExcelFillStyle.Solid;
fill.BackgroundColor.SetColor(Color.Gray);
fill.PatternColor = Color.Black;
fill.Gradient = ...
(Code sample for EPPLus @ http://zeeshanumardotnet.blogspot.com)
As the Visual C# Program Manager linked above says, there are limited situations where the With statement is more efficient, the example he gives when it is being used as a shorthand to repeatedly access a complex expression.
Using an extension method and generics you can create something that is vaguely equivalent to a With statement, by adding something like this:
public static T With<T>(this T item, Action<T> action)
{
action(item);
return item;
}
Taking a simple example of how it could be used, using lambda syntax you can then use it to change something like this:
updateRoleFamily.RoleFamilyDescription = roleFamilyDescription;
updateRoleFamily.RoleFamilyCode = roleFamilyCode;
To this:
updateRoleFamily.With(rf =>
{
rf.RoleFamilyDescription = roleFamilyDescription;
rf.RoleFamilyCode = roleFamilyCode;
});
On an example like this, the only advantage is perhaps a nicer layout, but with a more complex reference and more properties, it could well give you more readable code.
hmm. I have never used VB.net in any depth, so I'm making an assumption here, but I think the 'using' block might be close to what you want.
using defines a block scope for a variable, see the example below
using ( int temp = someFunction(param1) ) {
temp++; // this works fine
}
temp++; // this blows up as temp is out of scope here and has been disposed
Here is an article from Microsoft that explains a bit more
EDIT: yeah, this answer is wrong - the original assumption was incorrect. VB's 'WITH' is more like the new C# object initialisers:
var yourVariable = new yourObject { param1 = 20, param2 = "some string" };
For me I was trying to auto generate code, and needed to reuse a simple variable like "x" for multiple different classes so that I didn't have to keep generating new variable names. I found that I could limit the scope of a variable and reuse it multiple times if I just put the code in a curly brace section {}.
See the example:
public class Main
{
public void Execute()
{
// Execute new Foos and new Bars many times with same variable.
double a = 0;
double b = 0;
double c = 0;
double d = 0;
double e = 0;
double f = 0;
double length = 0;
double area = 0;
double size = 0;
{
Foo x = new Foo(5, 6).Execute();
a = x.A;
b = x.B;
c = x.C;
d = x.D;
e = x.E;
f = x.F;
}
{
Bar x = new Bar("red", "circle").Execute();
length = x.Length;
area = x.Area;
size = x.Size;
}
{
Foo x = new Foo(3, 10).Execute();
a = x.A;
b = x.B;
c = x.C;
d = x.D;
e = x.E;
f = x.F;
}
{
Bar x = new Bar("blue", "square").Execute();
length = x.Length;
area = x.Area;
size = x.Size;
}
}
}
public class Foo
{
public int X { get; set; }
public int Y { get; set; }
public double A { get; private set; }
public double B { get; private set; }
public double C { get; private set; }
public double D { get; private set; }
public double E { get; private set; }
public double F { get; private set; }
public Foo(int x, int y)
{
X = x;
Y = y;
}
public Foo Execute()
{
A = X * Y;
B = X + Y;
C = X / (X + Y + 1);
D = Y / (X + Y + 1);
E = (X + Y) / (X + Y + 1);
F = (Y - X) / (X + Y + 1);
return this;
}
}
public class Bar
{
public string Color { get; set; }
public string Shape { get; set; }
public double Size { get; private set; }
public double Area { get; private set; }
public double Length { get; private set; }
public Bar(string color, string shape)
{
Color = color;
Shape = shape;
}
public Bar Execute()
{
Length = Color.Length + Shape.Length;
Area = Color.Length * Shape.Length;
Size = Area * Length;
return this;
}
}
In VB I would have used the With and not needed variable "x" at all. Excluding the vb class definitions of Foo and Bar, the vb code is:
Public Class Main
Public Sub Execute()
Dim a As Double = 0
Dim b As Double = 0
Dim c As Double = 0
Dim d As Double = 0
Dim e As Double = 0
Dim f As Double = 0
Dim length As Double = 0
Dim area As Double = 0
Dim size As Double = 0
With New Foo(5, 6).Execute()
a = .A
b = .B
c = .C
d = .D
e = .E
f = .F
End With
With New Bar("red", "circle").Execute()
length = .Length
area = .Area
size = .Size
End With
With New Foo(3, 10).Execute()
a = .A
b = .B
c = .C
d = .D
e = .E
f = .F
End With
With New Bar("blue", "square").Execute()
length = .Length
area = .Area
size = .Size
End With
End Sub
End Class
A big fan of With
here!
This is literally my current C# code:
if (SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.AccessTokenExpiry == null || SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.AccessTokenExpiry < DateTime.Now)
{
SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.Refresh();
_api = new SKYLib.AccountsPayable.Api.DefaultApi(new SKYLib.AccountsPayable.Client.Configuration { DefaultHeader = SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization.ApiHeader });
}
In VB it could be:
With SKYLib.AccountsPayable.Client.ApiAuthorization.Authorization
If .AccessTokenExpiry Is Nothing OrElse .AccessTokenExpiry < Now Then .Refresh()
_api = New SKYLib.AccountsPayable.Api.DefaultApi(New SKYLib.AccountsPayable.Client.Configuration With {DefaultHeader = .ApiHeaders}
End With
Much clearer I think. You could even tweak it to be more concise by tuning the With
variable. And, style-wise, I still have a choice! Perhaps something the C# Program Manager has overlooked.
As an aside, it's not very common to see this, but I have used it on occasion:
Instead of
Using oClient As HttpClient = New HttpClient
With oClient
.BaseAddress = New Uri("http://mysite")
.Timeout = New TimeSpan(123)
.PostAsync( ... )
End With
End Using
You can use
With New HttpClient
.BaseAddress = New Uri("http://mysite")
.Timeout = New TimeSpan(123)
.PostAsync( ... )
End With
You risk a wrist-slapping - as do I for posting! - but it seems that you get all the benefits of a Using
statement in terms of disposal, etc without the extra rigmarole.
NOTE: This can go wrong occasionally, so only use it for non-critical code. Or not at all. Remember: You have a choice ...
The with
keywork is introduced in C# version 9!
you can use it to create copy of object like follows
Person brother = person with { FirstName = "Paul" };
"The above line creates a new Person record where the LastName property is a copy of person, and the FirstName is "Paul". You can set any number of properties in a with-expression. Any of the synthesized members except the "clone" method may be written by you. If a record type has a method that matches the signature of any synthesized method, the compiler doesn't synthesize that method."
UPDATE:
At the time this answer is written, C#9 is not officially released but in preview only. However, it is planned to be shipped along with .NET 5.0 in November 2020
for more information, check the record types.
To make life a little easier you can use vertical selection to quickly edit things
http://joelabrahamsson.com/select-columns-of-text-in-visual-studio/
No, there is not.
As the Visual C# Program Manager linked above says, there are limited situations where the With statement is more efficient, the example he gives when it is being used as a shorthand to repeatedly access a complex expression.
Using an extension method and generics you can create something that is vaguely equivalent to a With statement, by adding something like this:
public static T With<T>(this T item, Action<T> action)
{
action(item);
return item;
}
Taking a simple example of how it could be used, using lambda syntax you can then use it to change something like this:
updateRoleFamily.RoleFamilyDescription = roleFamilyDescription;
updateRoleFamily.RoleFamilyCode = roleFamilyCode;
To this:
updateRoleFamily.With(rf =>
{
rf.RoleFamilyDescription = roleFamilyDescription;
rf.RoleFamilyCode = roleFamilyCode;
});
On an example like this, the only advantage is perhaps a nicer layout, but with a more complex reference and more properties, it could well give you more readable code.
Source: Stackoverflow.com