#c# #generics #reflection
#c# #общие #отражение
Вопрос:
Я пытаюсь написать универсальный класс, передать ему некоторые типы, а затем получить к нему доступ через свойства.
Я написал этот код:
class Factory<T1, T2> where T1 : Test, new()
where T2 : Test, new()
{
public T1 FirstType { get; set; }
public T2 SecondType { get; set; }
public Factory()
{
FirstType = new T1();
SecondType = new T2();
}
}
и я использую это так (OtherTest реализует тест):
Factory<Test, OtherTest> factory = new Factory<Test, OtherTest>();
factory.FirstType.MyMethod();
Затем я могу использовать свойства FirstType и SecondType, однако, если я изменю порядок:
Factory<OtherTest, Test> factory2 = new Factory<OtherTest, Test>();
Это будет иметь другое поведение, поскольку FirstType будет OtherTest . Я хотел бы передавать экземпляры и иметь возможность писать такой код:
Factory<Test, OtherTest> factory = new Factory<Test, OtherTest>();
factory.Test.MyMethod(); //I want to generate properties named after class
factory.OtherTest.MyMethod();
Могу ли я сделать это во время компиляции?
Комментарии:
1. Боюсь, я не совсем понимаю, в чем заключается ваш вопрос. Все в порядке до тех пор, пока » Я хотел бы передавать экземпляры и иметь возможность писать такой код… Могу ли я сделать это во время компиляции? «, и, боюсь, я понятия не имею, что вы пытаетесь сделать во время компиляции.
2. У меня есть очень наглядный пример. Я хочу создать фабрику
Factory<A, B> factory = new Factory<A, B>();
, а затем получить доступ к ее полям по имени классов (A, B). Я в основном хочу переименовать FirstType / SecondType в имена типов T1, T2 (A, B или Test, OtherTest).3. Правильно. Нет, вы не можете этого сделать.
4. Не во время компиляции, нет.
5. Вы могли бы взглянуть на генерацию кода и текстовые шаблоны T4 .
Ответ №1:
Вы не можете изменять имена свойств с помощью параметров универсального типа. Самое близкое, что вы можете получить, — это словарь
Dictionary<string, Test> Tests;
Затем вы можете использовать typeof(T1).Name
и nameof
для безопасного предоставления имен свойств.
Tests.Add(typeof(T1).Name, new T1());
Test test = Tests[nameof(FirstType)];
Комментарии:
1. Действительно ли нет способа обернуть
Tests[nameof(FirstType)];
во что-то вродеTests.FirstType;
илиTests.Get(FirstType);
?2. @e.e, как все до сих пор говорили, нет. Это не то, что поддерживают дженерики C #.
3. Ну, вы можете использовать
dynamic
тип C # и класс ExpandoObject . Но он разрешает имена во время выполнения и не является типобезопасным.