Tcl: Как я могу вызвать proc из другого пространства имен, а также передать свой proc переменную из его пространства имен?

Связывание обычно не работает с полями. Большинство привязок основаны, в частности, на модели ComponentModel PropertyDescriptor, которая (по умолчанию) работает над свойствами. Это дает возможность уведомлений, проверки и т. Д. (Ни одна из которых не работает с полями).

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

[DataContract]
public class StatusInfo
{
    [DataMember] public int Total {get;set;}
    [DataMember] public string Authority {get;set;}
}

Теперь он будет вести себя так, как вы думаете. Если вы хотите, чтобы это была неизменяемая структура, это было бы нормально (но привязка к данным была бы в одностороннем порядке, конечно):

[DataContract]
public struct StatusInfo
{
    [DataMember] public int Total {get;private set;}
    [DataMember] public string Authority {get;private set;}

    public StatusInfo(int total, string authority) : this() {
        Total = total;
        Authority = authority;
    }
}

Однако я бы сначала спросил, почему это структуры в первую очередь. Редактировать структуру на языках .NET очень редко. Имейте в виду, что прокси-сервер WCF «mex» будет создавать его как класс у потребителя в любом случае (если вы не используете совместное использование сборок).


В ответ на ответ «зачем использовать структуру» ответ ( «unknown (google)»):

Если это ответ на мой вопрос, это неправильно во многих отношениях. Во-первых, типы значений как переменные обычно выделяются (сначала) в стеке. Если они попадают в кучу (например, в массиве / списке), нет большой разницы в накладных расходах от класса - небольшой бит заголовка объекта плюс ссылка. Структуры всегда должны быть маленькими. Что-то с несколькими полями будет чрезмерно крупным и будет либо убивать ваш стек, либо просто вызвать медленность из-за блуждания. Кроме того, структуры должны быть неизменными - если вы действительно не знаете, что делаете.

Практически все, что представляет объект, должно быть бескомпромиссным.

Если вы попадаете в базу данных, скорость struct vs class является не-проблемой по сравнению с выходом из процесса и, вероятно, по сети. Даже если это немного медленнее, это ничего не значит по сравнению с тем, что нужно сделать правильно - т.е. рассматривать объекты как объекты.

Как некоторые метрики над объектами 1M:

struct/field: 50ms
class/property: 229ms

на основе следующего (разница в скорости в распределении объектов, а не в поле vs). Так что примерно в 5 раз медленнее, но все же очень, очень быстро. Поскольку это не будет вашим узким местом, преждевременно не оптимизируйте это!

using System;
using System.Collections.Generic;
using System.Diagnostics;
struct MyStruct
{
    public int Id;
    public string Name;
    public DateTime DateOfBirth;
    public string Comment;
}
class MyClass
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Comment { get; set; }
}
static class Program
{
    static void Main()
    {
        DateTime dob = DateTime.Today;
        const int SIZE = 1000000;
        Stopwatch watch = Stopwatch.StartNew();
        List<MyStruct> s = new List<MyStruct>(SIZE);
        for (int i = 0; i < SIZE; i++)
        {
            s.Add(new MyStruct { Comment = "abc", DateOfBirth = dob,
                     Id = 123, Name = "def" });
        }
        watch.Stop();
        Console.WriteLine("struct/field: "
                  + watch.ElapsedMilliseconds + "ms");

        watch = Stopwatch.StartNew();
        List<MyClass> c = new List<MyClass>(SIZE);
        for (int i = 0; i < SIZE; i++)
        {
            c.Add(new MyClass { Comment = "abc", DateOfBirth = dob,
                     Id = 123, Name = "def" });
        }
        watch.Stop();
        Console.WriteLine("class/property: "
                   + watch.ElapsedMilliseconds + "ms");
        Console.ReadLine();
    }
}
0
задан the_meter413 2 March 2019 в 00:13
поделиться

2 ответа

Вы можете делать то, что вы хотите, используя namespace upvar, который предназначен для просмотра переменных в другом пространстве имен:

namespace upvar $fooSpace $myValue fruit

В качестве альтернативы, вы можете использовать upvar, чтобы сделать это, но тогда вам нужно чтобы остановить замену имени переменной fooSpace на включение впоследствии разделителя пространства имен (или вы в конечном итоге говорите о переменной с пустым именем в этом пространстве имен, которое, вероятно, не существует). Этот контроль цитирования выполняется с помощью ${…} следующим образом:

upvar ${fooSpace}::$myValue fruit

(Вы также можете использовать ${fooSpace}::${myValue}, после синтаксического анализа все будет работать одинаково.)

Я рекомендую что вы используете namespace upvar, хотя: он немного более эффективен, потому что ему вообще не нужно повторно анализировать имена переменных.

0
ответ дан Donal Fellows 2 March 2019 в 00:13
поделиться

Как заставить мой процесс использовать переменную, определенную в fooSpace?

Вы используете upvar фиктивно, вы пропускаете аргумент уровня, #0: [ 1116]

upvar "#0" [namespace current]::$myValue fruit

Кроме того, $fooSpace ссылается не на пространство имен fooSpace, а на локальную переменную proc с этим именем (отсюда и ошибка can't read "fooSpace": no such variable); поэтому:

[namespace current]::$myValue

, который превращается в

::fooSpace::$myValue

Но я не думаю, что могу сделать переменную $ myvalue в рамках моего процесса, либо

Зависит от того, что если вы хотите работать с переменной ссылки fruit, нет, команда variable этого не даст. Но вы, безусловно, можете ссылаться на переменные пространства имен следующим образом:

 variable $myValue

Незначительное предложение: myValue будет лучше придумано myVar или myVarName, потому что аргумент обозначает (пространство имен) имен переменных [1114 ] (не значения, хранящиеся в этих переменных).

0
ответ дан mrcalvin 2 March 2019 в 00:13
поделиться
Другие вопросы по тегам:

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