C # Используйте дженерики и деревья выражений для получения значений полей объекта - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть два класса с похожими полями:

Class Foo {
    string name;
    int val;
};

Class Bar {
    string name;
    int val;
};

Есть ли способ использовать Generics для получения имен полей и значений объектов этих классов? Что-то вроде:

string GetName<T> (T obj)
{
    //returns T.name
}

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

Обновление:

Я не контролирую определения классов Foo и Bar. Они будут выставлены мне в библиотеке и могут измениться.

Я могу использовать что-то вроде следующего:

Type myType = myObject.GetType();
var value = myType.GetProperty("name").GetValue(myObject, null);

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

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

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

public string GetName(Foo o) { return o.Name; }
public string GetName(Bar o) { return o.Name; }

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

GetName(eitherObject);

... и он будет безопасен для типов.

Вы можетена самом деле не используют дженерики, потому что у Foo и Bar отсутствует общий интерфейс, который предоставляет Name.

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

0 голосов
/ 13 сентября 2018

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

public class BaseEntity
{
    int val;
    protected string name;
    public string Name
    {
        get
        {
            return name; // Only get is exposed to prevent modifications
        }
    }
}

public class ClassA : BaseEntity
{
   // Other fields or methods
}

public class ClassB : BaseEntity
{
    // Other fields or methods
}
...