Подтвердить что ты не робот

С блочным эквивалентом в С#?

Я знаю VB.Net и пытаюсь расчистить свой С#. Есть ли эквивалент С блочным эквивалентом в С#?

Спасибо

4b9b3361

Ответ 1

Хотя С# не имеет прямого эквивалента для общего случая, С# 3 получает синтаксис инициализатора объекта для вызовов конструктора:

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

Для более подробной информации смотрите главу 8 С# in Depth. Вы можете бесплатно скачать ее с веб-сайта Manning.

(Отказ от ответственности - да, в моих интересах, чтобы книга попала в руки большего количества людей. Но, эй, это бесплатная глава, которая дает вам больше информации по связанной теме...)

Ответ 2

Это то, что менеджер программ Visual С# должен сказать: Почему С# не имеет инструкции 'with'?

Многие люди, включая дизайнеров языка С#, считают, что "с" часто наносит вред читаемости и является скорее бичем, чем благословением. это clearer, чтобы объявить локальную переменную со значимым именем и использовать эту переменную для выполнения нескольких операций на одном объекте, чем он должен иметь блок с своего рода неявным контекстом.

Ответ 3

Как сказано выше в связке "Диспетчер программ Visual С#", существуют ограниченные ситуации, в которых оператор "С" более эффективен, пример, который он приводит, когда он используется в качестве сокращенной формы для многократного доступа к сложному выражению.

Используя метод расширения и обобщения, вы можете создать нечто, что примерно эквивалентно оператору 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

Нет, нет.

Ответ 5

Около 3/4 вниз по странице в разделе Использование объектов:

VB:

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

С#:

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

Ответ 7

Я использую ключевое слово ref csharp. Например:

ref MySubClassType e = ref MyMainClass.MySubClass;

вы можете использовать ярлык, например: e.property вместо MyMainClass.MySubClass.property

Ответ 8

Самый простой синтаксис:

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

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

На самом деле такие дополнительные блоки кода очень удобны, если вы хотите повторно использовать имена переменных.

Ответ 9

Иногда вы можете уйти от выполнения следующих действий:

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)

Ответ 10

Я использовал этот способ:

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

SetHeadFontStyle/SetHeadFillStyle - это ExtMethod Диапазон, как показано ниже:

 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

Ответ 11

Большой поклонник With здесь!

Это буквально мой текущий код С#:

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. И, по стилю, у меня все еще есть выбор! Возможно, менеджер программы С# упустил из виду.

Кроме того, это не очень часто можно увидеть, но я использовал это время от времени:

Вместо

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 с точки зрения утилизации и т.д. без лишних проблем.

ПРИМЕЧАНИЕ. Иногда это может пойти не так, поэтому используйте его только для некритического кода. Или нет совсем. Помните: у вас есть выбор...

Ответ 12

Есть еще одна интересная реализация 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;

Вы можете просмотреть более подробную информацию по ссылке и исследовать примеры кода в Интернете.

Варианты использования

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

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

Наслаждайся, если хочешь!

Ответ 13

Я думаю, что шкалой для "с" является static using, но он работает только со статическими методами или свойствами. например

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

Дополнительная информация:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-static

Ответ 14

хмм. Я никогда не использовал VB.net на любой глубине, поэтому я делаю предположение здесь, но я думаю, что блок "using" может быть близок к тому, что вы хотите.

используя поле блока для переменной, см. пример ниже

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

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

Вот статья от Microsoft, которая объясняет немного больше


ИЗМЕНИТЬ: да, этот ответ неверен - исходное предположение было неверным. VB 'WITH' больше похож на новые инициализаторы объектов С#:

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

Ответ 15

Если существует несколько уровней объектов, вы можете получить аналогичную функциональность с помощью директивы "using":

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