У меня проблема с подстановочными знаками в generics в C#. Первый подход, чтобы запустить мой маленький пример, состоял в том, чтобы использовать объект как общий тип, потому что он является базовым классом всего.C# общий подтип супертипа
public class AttributeManager
{
private Dictionary<int, AttributeItem<object>> attributes = new Dictionary<int, AttributeItem<object>>();
public void add(AttributeItem<object> attribute)
{
if (hasAttribute(attribute)) {
return;
}
attributes.Add(attribute.getKey(), attribute);
}
}
public abstract class AttributeItem<T>
{
private int key;
private T attributeValue;
private AttributeManager attributeManager;
public AttributeItem(AttributeManager attributeManager, int key)
{
this.key = key;
this.attributeManager = attributeManager;
attributeManager.add(this); // this line does not work
}
public void setValue(T newValue)
{
attributeValue = newValue;
}
public T getValue()
{
return attributeValue;
}
}
Однако линия:
attributeManager.add (это);
не работает. В нем говорится, что для этого вызова не было перегруженного метода. Я думал, что «это» будет передано в AttributeItem, потому что объект должен быть суперклассом T. Итак, мой первый вопрос: почему этот актер не работает?
Мой второй подход был изменить AttributeManager использовать вид маски:
public class AttributeManager
{
private Dictionary<int, AttributeItem<????>> attributes = new Dictionary<int, AttributeItem<????>>();
/**
* This method will add a new AttributeItem if hasAttribute(AttributeItem) returns false.
*/
public void add<T>(AttributeItem<T> attribute)
{
if (hasAttribute(attribute)) {
return;
}
attributes.Add(attribute.getKey(), attribute); // this line fails
}
}
Но, как вы можете видеть, я понятия не имею, какой тип я должен передать в объявлении:
Dictionary<int, AttributeItem<????>> attributes
Так что мой второй вопрос: что мне нужно использовать вместо ?????
С уважением Роберт
А, да, у меня была такая же проблема при разработке решения, и я лично переделал его. Я думаю, вы пытаетесь избежать, находясь в объявлении класса AttributeManager? –
Да, правильно. Я не хочу, чтобы он тоже был родовым. Я хочу, чтобы он принимал любые атрибуты. –
Вместо этого вы можете использовать интерфейс и изменить свой AttributeItem так, чтобы он имел ограничение T: YourInterface? Таким образом, код будет выглядеть как частный словарь> attributes = new Dictionary >(); –