[C# Q&A] 제너릭 T를 인스턴스하는 방법이 뭘까요?

질문

제너릭 T를 인스턴스하고 싶습니다.
정확히는 IoC로 …

public class MainViewModel<TSampleViewModel> : BaseViewModel
    where TSampleViewModel : SampleViewModel
{

    public TSampleViewModel SampleMethod(string id, string name)
    {
        var sample = ?????? TSampleViewModel { Id = id, Name = name }; // <= 막히는 부분 입니다.
        // var sample = Mvx.IoCProvider.IoCConstruct<TSampleViewModel>(new[] { id, name });
        // 원하는 기대 값은 위에 코드와 같이 <T>를 new 생성하는 방법 입니다.

        return sample;
    }
}


// 1. new () 추가 없이 구현하는 방식이 궁금합니다.
// 이유는 new ()를 추가하면 상속 받는 클래스를 수정하고 수정하는 문제가 발생합니다.

// 2. 가능하면 IoC로 관리 가능한 상태면 좋겠습니다.
// 3. MvvmCross IoCConstruct를 MAUI에서 사용하는 컨테이너에 맞게 구현 할 수 있을까요?
/* public class MainViewModel<TSampleViewModel> : BaseViewModel
where TSampleViewModel : SampleViewModel, new ()
{
    public TSampleViewModel SampleMethod(string id, string name)
    {
        var sample = new TSampleViewModel { Id = id, Name = name };

        return sample;
    }
}
*/
public class SampleViewModel : BaseViewModel
{
    public string Id { get; set; }

    public string Name { get; set; }
}
    1. new () 추가 없이 구현하는 방식이 궁금합니다.
      CS0310 : 매개 변수가 없는 public 비추상 유형이어야 합니다. 이 발생합니다.
    1. 가능하면 IoC로 관리 가능한 상태면 좋겠습니다.
    1. MvvmCross IoCConstruct를 MAUI에서 사용하는 컨테이너에 맞게 구현 할 수 있을까요?

샘플 링크

  • 2023.09.19 - 14:10 : new () 예제 추가 되었습니다.

https://github.com/SSstupid/IDontKnow-This-/tree/NewQuestion/HowToInstanceTheGenericT/GenericTSampleApp



2023.09.19 - 14:10 업데이트

보충 및 질문 답변

정확하게 아는 부분이 아니라서;;;
  • 아주 높은 비율로 C# Q&A가 맞습니다. 제목 및 카테고리 수정합니다.

  • Mvx.IoCConstruct<T>로 들어오는 값을 Type에 맞게 인자와 같이 생성하는데 있습니다.
    <T>에는 여러 Type이 들어올 수 있으며 그 Type을 설정 및 관리 책임을 IoC에게 넘기는 것이 핵심입니다. 그러면 생명주기 관리도 같이 따라오는 것이 장점입니다.

  • new () 문제점

    • CS0310 : 매개 변수가 없는 public 비추상 유형이어야 합니다.

new() 를 쓰지 말아야 하나요?

  • Sample 업데이트 완료
    new () 예제 추가 되었습니다.
1개의 좋아요

C#의 제네릭 인스턴스 생성 질문인지
관련된 MAUI 질문인지 모호합니다.
Mvx.IoCConstuct의 동작성에 대한 설명이 부족합니다.

2개의 좋아요

아 코드에 정확한 질문 내용이 있군요 ^^;

2개의 좋아요

어쨌든 where: new()를 사용하지 못하는 이유는 여전히 모르겠습니다. 왜 new()를 쓰지 말아야 하나요?

2개의 좋아요
  1. Activator.CreateInstance를 이용한다.

  2. 인터페이스에서 해당 타입을 반환하는 추상 static 메서드를 정의하고, 하위 타입에서 구현한다

public interface ISampleViewModel
{
	string Id { get; set; }

	string Name { get; set; }

	static abstract T? Test<T>(string id, string name)
		where T : class, ISampleViewModel;
}

public class SampleViewModel : ISampleViewModel
{
    public string Id { get; set; }

	public string Name { get; set; }

	static T? ISampleViewModel.Test<T>(string id, string name) where T : class
	{
		if (typeof(T) != typeof(SampleViewModel))
		{
			return default;
		}

		return new SampleViewModel()
		{
			Id = id,
			Name = name
		} as T;
	}
}
2개의 좋아요

음… 예전에 포스팅해뒀던 게 있는데
https://blog.naver.com/vactorman/221197148106
이게 도움이 될라나요?ㅅ?

아 제네릭 관련된 내용이었군요… 도움이 안 되겠… ;;;;

4개의 좋아요

일반적인 응용 프로그램이라면 대충 다음과 같은 식의 코드로 해결할 수 있겠지만,

Type type = typeof(GenericT);
var ctor = type.GetConstructor(new[] { typeof(string) });
return ctor.Invoke(new object[] { text }) as GenericT;

현재 MAUI 프로젝트에서 Android용으로 개발하시려는 것 같은데 그런 환경에서는 Reflection이 지원되지 않으므로 저런 코드를 사용하면 아마 오류가 날 것입니다. Android Emulator에서 테스트해 보니까 동작을 하는군요. ^^

참고로, Mvx.IoCConstuct가 딱히 특별한 라이브러리가 아닙니다. 어차피 그것도 Reflection을 활용한 라이브러리에 불과합니다.

6개의 좋아요