programing

블록당량이 C#인 경우?

elecom 2023. 5. 28. 19:58
반응형

블록당량이 C#인 경우?

VB.VB를 요.인터넷을 하고 내 C#을 복습하려고 합니다.이 ?With블록당량(C#)?

C#이 일반적인 경우에 직접적으로 해당하지는 않지만 생성자 호출에 대한 C#3 gain 객체 이니셜라이저 구문은 다음과 같습니다.

var foo = new Foo { Property1 = value1, Property2 = value2, etc };

자세한 내용은 C# 8장의 깊이를 참조하십시오. 매닝의 사이트에서 무료로 다운로드할 수 있습니다.

(Disclaimer - 네, 책을 더 많은 사람들의 손에 맡기는 것이 제 이익입니다.하지만 관련 주제에 대한 더 많은 정보를 제공하는 무료 장입니다...)

Visual C# 프로그램 관리자는 다음과 같이 말합니다.C#에 'with' 문이 없는 이유는 무엇입니까?

C# 언어 디자이너를 포함한 많은 사람들은 'with'가 종종 가독성을 해치고 축복이라기보다는 저주에 가깝다고 믿습니다.로컬 변수를 의미 있는 이름으로 선언하고 해당 변수를 사용하여 하나의 개체에 대해 여러 작업을 수행하는 것이 암시적 컨텍스트를 가진 블록을 사용하는 것보다 더 명확합니다.

위에 링크된 Visual C# Program Manager가 말했듯이 With 문이 더 효율적인 상황은 제한적입니다. With 문이 복잡한 식에 반복적으로 액세스하기 위한 단축형으로 사용될 때 그가 제공하는 예입니다.

확장 방법과 제네릭을 사용하여 다음과 같은 것을 추가하여 With 문과 모호하게 동일한 것을 만들 수 있습니다.

    public static T With<T>(this T item, Action<T> action)
    {
        action(item);
        return item;
    }

람다 구문을 사용하여 사용할 수 있는 간단한 예를 보면 다음과 같은 것을 변경할 수 있습니다.

    updateRoleFamily.RoleFamilyDescription = roleFamilyDescription;
    updateRoleFamily.RoleFamilyCode = roleFamilyCode;

대상:

    updateRoleFamily.With(rf =>
          {
              rf.RoleFamilyDescription = roleFamilyDescription;
              rf.RoleFamilyCode = roleFamilyCode;
          });

이와 같은 예에서 유일한 장점은 더 나은 레이아웃일 수 있지만, 더 복잡한 참조와 더 많은 속성을 사용하면 더 읽기 쉬운 코드를 제공할 수 있습니다.

"오브젝트 사용" 섹션의 페이지 아래쪽으로 약 4분의 3:

VB:

With hero 
  .Name = "SpamMan" 
  .PowerLevel = 3 
End With 

C#:

//No "With" construct
hero.Name = "SpamMan"; 
hero.PowerLevel = 3; 

아니요, 없습니다.

with는 C#9에 되었습니다! 은 이것을 과 같은 수 .

Person brother = person with { FirstName = "Paul" };

"위 줄은 성 속성이 사용자의 복사본이고 이름이 "폴"인 새 사용자 레코드를 만듭니다.식을 사용하여 원하는 수의 속성을 설정할 수 있습니다."복제" 방법을 제외한 합성된 구성원은 사용자가 작성할 수 있습니다.레코드 유형에 합성된 메서드의 서명과 일치하는 메서드가 있으면 컴파일러는 해당 메서드를 합성하지 않습니다."

업데이트:

이 답변이 작성된 시점에서 C#9는 공식적으로 공개되지 않고 미리보기로만 공개됩니다.그러나 2020년 11월에 .NET 5.0과 함께 출하될 예정입니다.

자세한 내용은 레코드 유형을 확인하십시오.

제가 하는 일은 csharp ref 키워드를 사용하는 것입니다.예:

ref MySubClassType e = ref MyMainClass.MySubClass;

그러면 다음과 같은 바로 가기를 사용할 수 있습니다.e.propertyMyMainClass.MySubClass.property

가장 간단한 구문은 다음과 같습니다.

{
    var where = new MyObject();
    where.property = "xxx";
    where.SomeFunction("yyy");
}

{
    var where = new MyObject();
    where.property = "zzz";
    where.SomeFunction("uuu");
}

실제로 변수 이름을 다시 사용하려면 이러한 추가 코드 블록이 매우 유용합니다.

인수 누적기 패턴을 사용할 수 있습니다.

여기서 이에 대한 큰 논의:

http://blogs.msdn.com/csharpfaq/archive/2004/03/11/87817.aspx

C# 9 이상:

with키워드가 드디어 추가되었습니다!

만 합니다.recordtypes.

사용.

에 있인스턴스는쪽inst((인스턴스)의 .with키워드가 복사되고 오른쪽에 있는 모든 언급된 필드가 새 인스턴스를 반환하기 위해 해당 값으로 수정됩니다.

과 같은 다과같것있가정다니합다고들이은음이 .record예:예:

public record Model(string Prefix, string Location, bool CoolLocation, bool HasCitizens);

초기화된 원래 모델은 다음과 같습니다.

var model = new Model("Hello", "World", true, true);

다음을 제외한 모든 필드가 동일한 새 모델을 만들고 싶습니다.Location그리고.HasCitizens다음과 같은 방법으로 할 수 있습니다.

var model2 = model with { Location = "Mars", HasCitizens = false };
   // Prefix = "Hello"
   // Location = "Mars"
   // CoolLocation = true
   // HasCitizens = false

C# 10 이상:

with는 이제키워추사수있다니습용할가로를드▁can다ally▁be▁for▁now에 추가로 사용될 수 있습니다.struct그리고.anonymoustypes.

은 다음 문서를 참조하십시오.with키워드는 공식 문서에서 찾을 수 있습니다.

때로는 다음과 같은 작업을 수행하지 않아도 됩니다.

var fill = cell.Style.Fill;
fill.PatternType = ExcelFillStyle.Solid;
fill.BackgroundColor.SetColor(Color.Gray);
fill.PatternColor = Color.Black;
fill.Gradient = ...

(EPPLus용 코드 샘플 http://zeeshanumardotnet.blogspot.com )

나는 다음과 같은 방법을 사용했습니다.

        worksheet.get_Range(11, 1, 11, 41)
            .SetHeadFontStyle()
            .SetHeadFillStyle(45)
            .SetBorders(
                XlBorderWeight.xlMedium
                , XlBorderWeight.xlThick
                , XlBorderWeight.xlMedium
                , XlBorderWeight.xlThick)
            ;

SetHeadFontStyle / SetHeadFillStyle은 다음과 같은 ExtMethod of Range입니다.

 public static Range SetHeadFillStyle(this Range rng, int colorIndex)
 {
     //do some operation
     return rng;
 }

일부 작업을 수행하고 다음 작업을 위해 범위를 반환합니다.

그것은 Linq처럼 보입니다 :)

하지만 지금은 여전히 그것처럼 완전히 보일 수 없습니다 -- 속성 설정 값.

with cell.Border(xlEdgeTop)
   .LineStyle = xlContinuous
   .Weight = xlMedium
   .ColorIndex = xlAutomatic

의 팬.With 자!

이것은 말 그대로 제 현재 C# 코드입니다.

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 });
}

VB에서는 다음과 같습니다.

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

훨씬 더 명확한 것 같아요.더 간결하게 조정할 수도 있습니다.With변수.그리고, 스타일적으로, 나는 여전히 선택권이 있습니다!아마도 C# 프로그램 관리자가 간과한 부분일 것입니다.

별도로, 이것을 보는 것은 그리 흔한 일이 아니지만, 저는 가끔 그것을 사용해 왔습니다.

대신에

Using oClient As HttpClient = New HttpClient
    With oClient
        .BaseAddress = New Uri("http://mysite")
        .Timeout = New TimeSpan(123)
        .PostAsync( ... )
    End With
End Using

사용할 수 있습니다.

With New HttpClient
    .BaseAddress = New Uri("http://mysite")
    .Timeout = New TimeSpan(123)
    .PostAsync( ... )
End With

당신은 손목을 찰 위험을 감수하고 - 나도 게시물을 올립니다! - 하지만 당신은 모든 혜택을 받는 것처럼 보입니다.Using추가 리그마롤이 없는 폐기 등의 측면에서 진술.

참고: 가끔 오류가 발생할 수 있으므로 중요하지 않은 코드에만 사용하십시오.아니면 전혀.기억:선택할 수 있습니다...

삶을 조금 더 쉽게 만들기 위해 수직 선택을 사용하여 빠르게 편집할 수 있습니다.

http://joelabrahamsson.com/select-columns-of-text-in-visual-studio/

패턴이 있는 또 다른 흥미로운 구현이 있습니다.

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;

링크를 통해 더 자세한 정보를 검색하고 온라인 코드 샘플을 조사할 수 있습니다.

다양한 용도

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);
}

구조체 [값 유형]으로 작업하는 경우 유사한 확장 방법도 유용합니다.

public static TR Let<T, TR>(this T o, TR y) => y;

기본적으로 수정되지 않은 구조체 복사본이 반환되므로 With 메서드 이후에 적용할 수 있습니다.

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);

원한다면 즐기세요!

내 생각에 옷장과 관련된 것은static using그러나 정적인 방법이나 속성(예:

using static System.Math;
...
public double Area
{
   get { return PI * Pow(Radius, 2); } // PI == System.Math.PI
}

추가 정보: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static

저는 코드를 자동으로 생성하려고 했고, "x"와 같은 간단한 변수를 여러 개의 다른 클래스에 재사용하여 계속해서 새로운 변수 이름을 생성할 필요가 없었습니다.코드를 곱슬곱슬한 브레이스 섹션 {}에 넣으면 변수의 범위를 제한하고 여러 번 재사용할 수 있다는 것을 알게 되었습니다.

예를 참조하십시오.

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;
    }
}

VB에서는 "x" 변수를 포함하고 필요하지 않은 변수를 사용했을 것입니다.Foo와 Bar의 vb 클래스 정의를 제외하면 vb 코드는 다음과 같습니다.

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

흠. 저는 VB.net 을 깊이 있게 사용해 본 적이 없기 때문에 여기서 추측하고 있지만, '사용' 블록은 당신이 원하는 것에 가까울 수도 있다고 생각합니다.

변수에 대한 블록 범위를 정의합니다. 아래 예제를 참조하십시오.

using ( int temp = someFunction(param1) ) {
   temp++;  // this works fine
}

temp++; // this blows up as temp is out of scope here and has been disposed

여기 마이크로소프트의 기사가 있습니다. 좀 더 자세히 설명합니다.


편집: 네, 이 대답은 틀렸습니다 - 원래의 가정은 부정확했습니다.VB의 'WITH'는 새로운 C# 객체 이니셜라이저에 더 가깝습니다.

var yourVariable = new yourObject { param1 = 20, param2 = "some string" };

여러 수준의 개체가 있는 경우 "사용" 지침을 사용하여 유사한 기능을 얻을 수 있습니다.

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;
}

언급URL : https://stackoverflow.com/questions/481725/with-block-equivalent-in-c

반응형