Как сделать шаблонную специализацию в C #

Для второй страницы

protected void Page_Load(object sender, EventArgs e)
{
    if (Session["value"] != null)
    {
        Label1.Text = Session["value"].ToString();

    }
    else 
    {
        Label1.Text = "Sorry,Please enter the value  ";
    }
}
80
задан BartoszKP 3 December 2018 в 14:25
поделиться

4 ответа

Принятие Вы говорите о шаблонной специализации, поскольку это может быть сделано с шаблонами C++ - функция как это, не действительно доступно в C#. Это вызвано тем, что дженерики C# не обрабатываются во время компиляции и являются больше функцией времени выполнения.

Однако можно достигнуть подобного эффекта с помощью методов расширения C# 3.0. Вот пример, который показывает, как добавить дополнительный метод только для MyClass<int> тип, который является точно так же, как шаблонная специализация. Отметьте однако, что Вы не можете использовать это для сокрытия реализации по умолчанию метода, потому что компилятор C# всегда предпочитает стандартные методы для дополнительных методов:

class MyClass<T> {
  public int Foo { get { return 10; } }
}
static class MyClassSpecialization {
  public static int Bar(this MyClass<int> cls) {
    return cls.Foo + 20;
  }
}

Теперь можно записать это:

var cls = new MyClass<int>();
cls.Bar();

, Если бы Вы хотите иметь случай по умолчанию для метода, который использовался бы, когда никакая специализация не обеспечивается, чем, я верю записи одного дженерика Bar, дополнительный метод должен добиться цели:

  public static int Bar<T>(this MyClass<T> cls) {
    return cls.Foo + 42;
  }
59
ответ дан Tomas Petricek 3 December 2018 в 14:25
поделиться
  • 1
    быть категорически не согласным. Вы просто сделали код тяжелее, чтобы считать и протестировать на ошибки. разрядность кода! = кодируйте качество. – Tom Carchrae 21 May 2013 в 14:39

В C# самое близкое к специализации должно использовать более - определенная перегрузка; однако, это является хрупким, и не покрывает каждое возможное использование. Например:

void Foo<T>(T value) {Console.WriteLine("General method");}
void Foo(Bar value) {Console.WriteLine("Specialized method");}

Здесь, если компилятор знает типы в компиляции, он выберет самое определенное:

Bar bar = new Bar();
Foo(bar); // uses the specialized method

Однако....

void Test<TSomething>(TSomething value) {
    Foo(value);
}

будет использовать Foo<T> даже для TSomething=Bar, поскольку это записывается в во время компиляции.

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

В основном, C# просто не хочет, чтобы Вы работали со специализациями, за исключением полиморфизма:

class SomeBase { public virtual void Foo() {...}}
class Bar : SomeBase { public override void Foo() {...}}

Здесь Bar.Foo будет всегда решать к корректному переопределению.

83
ответ дан Robert Harvey 3 December 2018 в 14:25
поделиться
  • 1
    There' s никакой смысл к булевской переменной switch, it' s просто if / else. – Kevin 21 May 2013 в 15:13

Если Вы просто хотите протестировать, если тип получен из XYZ, то можно использовать:

theunknownobject.GetType().IsAssignableFrom(typeof(XYZ));

Если так, можно бросить "theunknownobject" к XYZ и вызвать alternativeFunc () как это:

XYZ xyzObject = (XYZ)theunknownobject; 
xyzObject.alternativeFunc();

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

0
ответ дан Jeroen Landheer 3 December 2018 в 14:25
поделиться
  • 1
    Вы Имеете в виду - Вы don' t подписываются на " Если бы это было твердо к программе, должно быть трудно понять "?;-) пример кода, бросаемый здесь в вопросе и ответах, действительно испытывает недостаток в понятных именах в переменной и константах, которые сделали бы функцию и цель немного более очевидными. – Rawheiser 21 May 2013 в 16:50

При добавлении промежуточного класса и словаря возможна специализация .

Чтобы специализироваться на T, мы создаем общий интерфейс с методом, называемым, например, Apply. Для конкретных классов этот интерфейс реализован, определяя метод Apply, специфичный для этого класса. Этот промежуточный класс называется классом черт.

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

Вместо того, чтобы указывать его вручную, класс свойств также можно сохранить в глобальном IDictionary . Затем его можно найти и вуаля, у вас есть настоящая специализация.

Если удобно, вы можете выставить его в методе расширения.

class MyClass<T>
{
    public string Foo() { return "MyClass"; }
}

interface BaseTraits<T>
{
    string Apply(T cls);
}

class IntTraits : BaseTraits<MyClass<int>>
{
    public string Apply(MyClass<int> cls)
    {
        return cls.Foo() + " i";
    }
}

class DoubleTraits : BaseTraits<MyClass<double>>
{
    public string Apply(MyClass<double> cls)
    {
        return cls.Foo() + " d";
    }
}

// Somewhere in a (static) class:
public static IDictionary<Type, object> register;
register = new Dictionary<Type, object>();
register[typeof(MyClass<int>)] = new IntTraits();
register[typeof(MyClass<double>)] = new DoubleTraits();

public static string Bar<T>(this T obj)
{
    BaseTraits<T> traits = register[typeof(T)] as BaseTraits<T>;
    return traits.Apply(obj);
}

var cls1 = new MyClass<int>();
var cls2 = new MyClass<double>();

string id = cls1.Bar();
string dd = cls2.Bar();

См. Эту ссылку на мой недавний блог и последующие действия для подробного описания и примеров.

15
ответ дан 24 November 2019 в 09:52
поделиться
Другие вопросы по тегам:

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