Ссылаясь на атрибуты в универсальных типах? - PullRequest
0 голосов
/ 22 июля 2011

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

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

Может быть, то, что я спрашиваю, может быть лучше передано в коде - это нерабочая функция, чтобы проиллюстрировать то, что я пытаюсь сделать, как мне кажется логичным, что это должно работать, фактически не зная, как это написать :

public static int AFunctionIsThis<DataType, int DataType.Value>(DataType passedrecord)
{
    temp = passedrecord.Value * 2 + 1;

    return temp;
}

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

int NewVariable = AFunctionIsThis<ThisIsAStruct, ThisIsAStruct.AnIntAttribute>(ThisIsADeclaredStruct);

Большое спасибо,

Hanii Puppy.

Ответы [ 4 ]

1 голос
/ 22 июля 2011

Вы не можете указывать элементы, которые должен содержать универсальный тип, вы можете указать только универсальный тип данных.

Вы бы использовали интерфейс, в котором определено свойство:

public interface IHaveValue {
  int Value { get; }
}

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

public static int AFunctionIsThis<T>(T passedrecord) where T : IHaveValue {
  return passedrecord.Value * 2 + 1;
}

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

public static int AFunctionIsThis(IHaveValue passedrecord) {
  return passedrecord.Value * 2 + 1;
}

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

0 голосов
/ 22 июля 2011

(Для начала обратите внимание, что слово «атрибут» имеет другое значение в .NET от смысла ООП.)

Используйте делегатов Converter<T,int> и Action<T,int> для получения и установки члена соответственно.

, например

public static int AFunctionIsThis<DataType>(DataType passedrecord, Converter<DataType,int> getter)
{
    temp = getter(passedrecord) * 2 + 1;

    return temp;
}

и затем назовите это

AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty);

Если вам также нужно установить значение, вы можете использовать

AFunctionIsThis(ThisIsADeclaredStruct, x => x.AnIntProperty, (x, v) => { x.AnIntProperty = v; });

или сотворите магию с Expression<Converter<T>>, чтобы вытащить ссылку на элемент и создать соответствующий установщик.

0 голосов
/ 22 июля 2011

То, что вы хотите сделать, это определить универсальный метод, который принимает только T, который реализует определенный интерфейс или является производным от определенного базового класса, который имеет член int с именем Value.например:

public interface IClass { int Value{get;set;} }
    public class ExampleImpl : IClass
    {
        int Value{get;set;}
        /* Additional Members\methods here */
    }
    public class HelperClass
    {
    public static int GenMethod<T>(T item) where T:IClass
    {
        return item.Value * 2 + 1;
    }
    }
0 голосов
/ 22 июля 2011

Щенок Хании:

Короче говоря, да, вы должны быть в состоянии делать то, что делаете, но вот синтаксис, который работает:

public static int AFunctionIsThis<T>(T passedRecord) where T : DataType
{
    var temp = passedRecord.Value;
    return temp;
}

public class DataType
{
    public int Value { get; set; }
}

Надеюсь, это поможет. Dave

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...