Псевдоним открытого типа C#?

То, что я хочу сделать, записать некоторые классы в C# в новом пространстве имен, которые действуют как классы обертки для классов в другом пространстве имен. Иногда класс обертки не нужен, но я все еще хочу соответствующий класс в новом пространстве имен. И я хочу точную копию класса. Существует ли способ определить класс в новом пространстве имен путем обращения к определению другого класса? Другими словами, я хочу псевдоним.

Разъясниться, что я имею в виду, если существующее пространство имен называют "Namespace1" и новым пространством имен, называют "Namespace2", с помощью кода как это в Namespace2:

using Class1 = Namespace1.Class1;

не работал бы потому что Namespace2.Class1 не существовал бы. Class1 был бы только искажен "частный" к Namespace2 и не "общедоступный" к Namespace2. Если я мог бы использовать Namepsace2.Class1 снаружи пространства имен, и если это все еще относилось бы к Namespace1.Class1, затем это было бы тем, что я хочу.

Я полагал, что мог бы быть способ выполнить это с атрибутами или отражением, возможно. Если были некоторые директивы препроцессору или макросы, которые могли бы скопировать код, который будет работать также, но очевидно C# не имеет ничего как этот.

6
задан YWE 19 January 2010 в 14:15
поделиться

6 ответов

Похоже, вам нужно отобразить определение одного класса в другое.

Это можно сделать вручную (через множество кодов котельной) или автоматически через инструмент, подобный Automatper .

2
ответ дан 10 December 2019 в 02:47
поделиться

Вы можете использовать с использованием Создать псевдоним к типу :

using Project = PC.MyCompany.Project;
4
ответ дан 10 December 2019 в 02:47
поделиться

Да, вы можете сделать это, если я правильно понимаю здесь MSDN MSDN Attright a MSDN MSDN на Alias ​​Nameswance Pasting

вот волшебство

using colAlias = System.Collections

, поэтому я сглаживающую систему. пространство имен.

Вот пример

using colAlias = System.Collections;
namespace System
{
    class TestClass
    {
        static void Main()
        {
            // Searching the alias:
            colAlias::Hashtable test = new colAlias::Hashtable();
        // Add items to the table.
        test.Add("A", "1");
        test.Add("B", "2");
        test.Add("C", "3");

        foreach (string name in test.Keys)
        {
            // Seaching the gloabal namespace:
            global::System.Console.WriteLine(name + " " + test[name]);
        }
    }
}

}

0
ответ дан 10 December 2019 в 02:47
поделиться

Если вы определяете класс в другом пространстве имен, это будет другой класс. MyNewnameSpace.myclass и myoldnamepace.myclass - два различных типа .NET.

Вы можете легко инкапсулировать все публичные API вашего первого класса в новом классе, но это потребует некоторый код котельной. AOP может обеспечить способ сделать это просто, используя что-то вроде postsharp (с пользовательским фильтром).

2
ответ дан 10 December 2019 в 02:47
поделиться

Проблема заключается в том, что библиотека выражений создает исключение, если заданы два аргумента несовпадающей возможности использования значения null. Вот простое репро:

Expression<Func<DateTime?>> ex1 = ()=>DateTime.Now;
Expression<Func<DateTime>> ex2 = ()=>DateTime.Now;
var ex3 = Expression.GreaterThan(ex1.Body, ex2.Body);

Мне непонятно, жучок это или нет; правила C # требуют, чтобы в этом сценарии операнд, не допускающий значения NULL, был преобразован в операнд, допускающий значение NULL, и использовалась форма сравнения, не допускающая значения NULL. Однако , библиотека дерева выражений не обязана следовать правилам C # , потому что, конечно, библиотека дерева выражений может использоваться для представления выражений C #, выражений Python, выражений JScript, выражений VB и так далее; он не может следовать всем правилам любого возможного языка.

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

    static Expression MyGreaterThan(Expression e1, Expression e2)
    {
        if (IsNullableType(e1.Type) && !IsNullableType(e2.Type))
            e2 = Expression.Convert(e2, e1.Type);
        else if (!IsNullableType(e1.Type) && IsNullableType(e2.Type))
            e1 = Expression.Convert(e1, e2.Type);
        return Expression.GreaterThan(e1, e2);
    }
    static bool IsNullableType(Type t)
    {
        return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
    }

Однако, обратите внимание, что это не проверяет, что типы e1 и e2 отличаются только нулевыми значениями; если передать значение int, допускающее значение null, и двойное выражение, не допускающее значения null, случаются плохие вещи. Я оставляю это как упражнение, чтобы реализовать лучшую логику, которая проверяет, имеют ли два выражения тип, который отличается только нулевая способность.

-121--1380350-

Было бы здорово, если бы был какой-то волшебный атрибут, который я мог бы просто добавить к свойству в «автоэкспрессию» свойство и сделать LinqToSql счастливым, вместо того, чтобы обернуть его в Выражение <... >

Есть, очень почти. Вы все еще должны сделать некоторые работы, но Дэмиен Guard и друзья сделали трудное для вас: Клиентские свойства и любой удаленный LINQ провайдер

Круто, что он работает с любым LINQ провайдер, который поддерживает выражения вы используете.

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

-121--1862543-

Классы обертки WRT, я много раз обнаруживаю, что люди переносят классы только для расширения функциональности, а не для выражения отношения is-a. В этих случаях можно рассмотреть Методы расширения .

Это позволяет писать методы для существующих классов, а не выводить только для добавления дополнительных функциональных возможностей. Для типа

/// <summary>
/// ICollectionExtensions
/// </summary>
internal static class ICollectionExtensions
{
    public static void AddNew<T>(this ICollection<T> self, T data)
    {
        if (self != null && !self.Contains(data))
        {
            self.Add(data);
        }
    }
}

можно использовать .AddNew () для типов ICollection < T > .

0
ответ дан 10 December 2019 в 02:47
поделиться

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

0
ответ дан 10 December 2019 в 02:47
поделиться