Действительно ли возможно передать свойства как или “касательно” параметров?

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

В нетипизированном лямбда-исчислении все члены являются лямбда-членами, и единственная операция, которая может быть выполнена на члене, применяется к другому члену. Следовательно, все операции всегда приводят либо к бесконечной рекурсии, либо к лямбда-термину, но никогда не сигнализируют об ошибке.

Однако если бы мы увеличили нетипизированное лямбда-исчисление с примитивными числами и арифметическими операциями, тогда мы могли бы выполнять бессмысленные операции , добавляя вместе два лямбда-члена: (λx.x) + (λy.y). Можно утверждать, что единственная нормальная задача - сигнализировать об ошибке, когда это происходит, но чтобы это сделать, каждое значение должно быть помечено индикатором, указывающим, является ли этот термин лямбда-термином или числом. Затем оператор добавления проверяет, действительно ли оба аргумента помечены как числа, а если они нет, сообщите об ошибке. Обратите внимание, что эти теги являются типами not , потому что типы являются свойствами программ, а не значениями, создаваемыми этими программами.

Uni-typed language, который делает это, называется динамически типизированным.

Все языки, такие как JavaScript, Python и Ruby, являются унифицированными. Опять же, оператор typeof в JavaScript и функция type в Python имеют вводящие в заблуждение имена; они возвращают теги, связанные с операндами, а не их типы. Аналогично, dynamic_cast в C ++ и instanceof в Java do not делают проверки типа.

28
задан Binary Worrier 19 February 2009 в 09:57
поделиться

3 ответа

Извинения за короткий ответ, но не, спецификация языка C# запрещает его.

Видят этот ответ к другому вопросу видеть то, что происходит, когда Вы пробуете. Это также говорит, почему Вы не должны делать свойство просто быть общедоступным полем для обхождения ограничения.

Hope это помогает

РЕДАКТИРОВАНИЕ: Вы спрашиваете Почему?

Вы передаете переменную out или ref параметр, Вы на самом деле передаете адрес (или местоположение в памяти) переменной. В функции компилятор знает, где переменная действительно, и получает и пишет значения в тот адрес.

свойство А похоже на значение, торцы, это - на самом деле пара функций, каждого с различной подписью. Таким образом для передачи свойства необходимо было бы на самом деле передать два указателя функции, один для получения, и один для набора.

Thats совершенно другая вещь передать функции, чем адрес переменной

т.е. один переменный v's адреса два указателя функции.

Обновление
, Почему не делает C# просто, заботится об этом для нас?

я не Eric Lippert , но я буду делать попытку того, почему

, Что должно подпись функции, которую Вы вызываете быть?
Позволяет, говорят, что Вы хотите звонить void MyFn(ref int i), который должен остаться тем путем, или он должен измениться, чтобы сказать, что мы также позволяем свойства? Если это изменяется на некоторый синтаксис как void MyFn(prop_ref int i) затем, это довольно бесполезно, Вы не можете передать свойства библиотечным функциям или стороннему коду, который не был написан со специальным prop_ref модификатором. Так или иначе я думаю, что Вы предлагаете, чтобы это не должно было отличаться.

Теперь позволяет, говорят MyFn передачи i к функции COM или вызову WinAPI, передавая адрес i (т.е. за пределами .NET, касательно). Если это - свойство, как Вы получаете адрес i? Не может быть никакого фактического интервала под свойством для получения адреса. Вы делаете то, что делает VB.Net?

Vb. Сетевой компилятор определяет, когда свойство передается как аргумент ByRef методу. В той точке это объявляет переменную, копирует свойство в переменную, передает переменную byref и затем после того, как метод называют, копирует переменную назад в свойство. т.е.

MyFunc(myObject.IntProperty)

становится

Dim temp_i As Integer = myObject.IntProperty
MyFunc(temp_i)
myObject.IntProperty = temp_i

, Любых побочных эффектов свойства не происходит до MyFunc возвраты, которые могут вызвать все виды проблем и привести к [1 116] очень тонкие ошибки.

По моему скромному мнению Vb. Сетевое решение этой проблемы также повреждается, таким образом, я не собираюсь признавать что как ответ.

, Как Вы думаете, компилятор C# должен обработать это?

38
ответ дан Community 14 October 2019 в 10:57
поделиться

Другие объяснили, что Вы не можете сделать этого в C#. В VB.NET Вы можете делать это, даже с опцией, strict/explicit на:

Option Strict On
Option Explicit On
Imports System.Text

Module Test

   Sub Main()
       Dim sb as new StringBuilder
       Foo (sb.Length)
   End Sub

   Sub Foo(ByRef x as Integer)
   End Sub

End Module

вышеупомянутый код эквивалентен этому коду C#:

using System.Text;

class Test
{
     static void Main()
     {
         StringBuilder sb = new StringBuilder();
         int tmp = sb.Length;
         Foo(ref tmp);
         sb.Length = tmp;
     }

     static void Foo(ref int x)
     {
     }
}

Лично я рад, что C# не имеет этого - он пачкает воды довольно много, особенно с точки зрения значения свойства, если параметр устанавливается в рамках метода, но затем исключение выдается.

РЕДАКТИРОВАНИЕ: Согласно просьбе мое обоснование относительно того, почему я верю передающим свойствам в, пачкает воды. Если Вы передаете нормальную переменную ссылкой, то та переменная оценена каждый раз, когда на нее ссылаются в рамках метода. Если значение изменяется по некоторым причинам (например, как побочный эффект некоторой другой работы в методе) затем, что изменение будет сразу видимо в методе. Это не имеет место, если Вы передаете свойство ссылкой в VB.NET: метод считывания свойства вызывается однажды, и затем метод set свойства вызывается однажды. Это не похоже, Вы являетесь передающими в, "вот , свойство - получает и установило от этого каждый раз, когда Вы используете параметр".

Вот полный пример, где передача поля и передача совершенно тривиального свойства в.NET имеют совсем другие результаты:

Option Strict On
Option Explicit On
Imports System.Text

Class Test

   Dim counter as Integer

   Property CounterProperty As Integer
       Get
           Return counter
       End Get
       Set (ByVal value as Integer)
           counter = value
       End Set
   End Property

   Sub Increment
       counter += 1
   End Sub

   Shared Sub Main()
       Dim t as new Test()
       Console.WriteLine("Counter = {0}", t.counter)
       t.Foo(t.counter)
       Console.WriteLine("Counter = {0}", t.counter)

       t.CounterProperty = 0
       Console.WriteLine("CounterProperty = {0}", t.CounterProperty)
       t.Foo(t.CounterProperty)
       Console.WriteLine("CounterProperty = {0}", t.CounterProperty)
   End Sub

   Sub Foo(ByRef x as Integer)
       x = 5
       Increment
       Increment
       Increment
       x += 1
   End Sub

End Class
12
ответ дан Jon Skeet 14 October 2019 в 10:57
поделиться

Вместо этого необходимо сделать что-то вроде этого

WhatEverTheType name;

Test(out name);

// Choose one of the following construction

Person p = new Person();
p.Name = name;

Person p = new Person(name);
Person p = new Person(Name => name);
0
ответ дан Fabian Vilers 14 October 2019 в 10:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: