Как вы думаете, общие свойства будут полезны в .NET? - PullRequest
7 голосов
/ 17 марта 2009

Я не говорю о универсальных классах, которые объявляют свойства или поля с типом универсального параметра. Я говорю о универсальных свойствах, которые можно применять как к универсальным, так и к неуниверсальным классам.

Я не об этом:

public class Base<T>
{
    public T BaseProperty { get; set; }
}

Я говорю об этом:

public class Base
{
    public T BaseProperty<T>
    {
       get
       {
          // Insert magic
       }
       set
       {
          // Insert magic
       }
    }
}

Или это:

public class Base<U>
{
    public T BaseProperty<T>
    {
       get
       {
          // Insert magic
       }
       set
       {
          // Insert magic
       }
    }

    public U OtherBaseProperty { get; set; }
}

Использование будет выглядеть примерно так:

var b = new Base();
b.BaseProperty<int> = 42;
int i = b.BaseProperty<int>;
b.BaseProperty<string> = "Hi";
string s = b.BaseProperty<string>;

Или для второго примера:

var b = new Base<string>();
b.BaseProperty<int> = 42;
int i = b.BaseProperty<int>;
b.OtherBaseProperty = "Hi";
string s = b.OtherBaseProperty;

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

Например, это:

b.BaseProperty<int> = 42;

Нужно обрабатывать иначе:

b.BaseProperty<string> = "Hi";

Я бы предполагал, что для каждого типа T, если метод get вызывается до вызова метода set, возвращается значение по умолчанию (T). Когда вызывается метод установки, значение сохраняется для каждого типа T, поэтому при последующем вызове метода получения возвращается предыдущее значение, установленное для этого типа.

Обратите внимание, что в свойствах слоев есть только методы.

Как вы думаете, это было бы полезно?

Ответы [ 7 ]

10 голосов
/ 17 марта 2009

У меня была пара раз, когда мне бы понравилась возможность сделать это, да.

Однако, синтаксис был бы довольно уродливым, и он достаточно редко полезен, я думаю, что я предпочитаю просто смириться с этим и использовать общие методы.

1 голос
/ 13 апреля 2012

хорошо, у меня есть ситуация, когда нужно универсальное свойство в неуниверсальном классе.

Например, у вас есть класс IComponent, который хочет предоставить своему родительскому IContainer свойство Parent, поскольку компонент может принадлежать к любому типу контейнера. поэтому вам нужно предоставить универсальное свойство, а не универсальный метод

Component c = new Component();
Container p = new Container();
p.Add(c);

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

c.Parent.ContainerProperty;
c.Parent.ContainerMethod();

скорее используя многословный метод, такой как

c.Parent().ContainerProperty;
c.Parent().ContainerMethod();

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

1 голос
/ 17 марта 2009

Вот один пример, где это было бы удобно для меня, если бы это было возможно.

var settings = new Settings();  
int timeout = settings<int>["CacheInMinutes"];

Где настройки загружают XML-файл переменных конфигурации.

Это, по сравнению с:

var settings = new Settings();  
int timeout = int.Parse(settings["CacheInMinutes"]);  

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

1 голос
/ 17 марта 2009

номер

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

Но свойства имеют смысл только как уникально именованные значения с определенным содержанием. «Общие свойства», как вы предлагаете, на самом деле сводятся к одноименным свойствам с разной подписью и различным содержанием.

1 голос
/ 17 марта 2009

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

1 голос
/ 17 марта 2009

№.

0 голосов
/ 17 марта 2009

Если по какой-то причудливой причине вы решили, что хотите, вы можете подделать это методами:

public class Thing
{
    Dictionary<Type, object> xDict = new Dictionary<Type,object>();
    public void set_X<T>(T x)
    {
        xDict[typeof(T)] = x;
    }
    public T get_X<T>()
    {
        return (T)xDict[typeof(T)];
    }
}

Почему вы хотите, это совсем другой вопрос. Как правило, имеет смысл начинать с того, что вы хотите сделать, чем с того, как вы хотите это сделать.

...