C # 새 T () 만들기


159

다음 코드를 사용하여 시도했지만 실패한 것을 볼 수 있습니다.

protected T GetObject()
{
    return new T();
}

도움을 주시면 감사하겠습니다.

편집하다:

상황은 다음과 같습니다. 표준화 된 방법으로 모든 컨트롤러에서 파생 할 수있는 사용자 정의 컨트롤러 클래스를 가지고 놀고있었습니다. 따라서 컨텍스트에서 컨트롤러 유형의 객체의 새 인스턴스를 만들어야했습니다. 따라서 글을 쓰는 시점은 다음과 같습니다.

public class GenericController<T> : Controller
{
    ...

    protected T GetObject()
    {
        return (T)Activator.CreateInstance(ObjectType);
    }        

    public ActionResult Create()
    {
        var obj = GetObject()

        return View(obj);
    }

그래서 반사가 가장 쉽다고 결정했습니다. 확실히 질문의 초기 진술이 주어 졌을 때, 올바른 것으로 표시하기에 가장 적합한 대답은 new () 제약 조건을 사용하는 것이 었다는 데 동의합니다. 나는 그것을 고쳤다.


27
아니요, 당신이하려는 것과 실패한 것이 보이지 않습니다. 컨텍스트, 오류 메시지 및 설명이없는 작업 프로그램의 일부가 될 수있는 코드 조각이 있습니다.
Ben Voigt 2016 년

17
오답을 선택했을 때 나는 그것을 싫어한다!
David Heffernan

답변:


409

새로운 구속 조건 살펴보기

public class MyClass<T> where T : new()
{
    protected T GetObject()
    {
        return new T();
    }
}

T기본 생성자가없는 클래스 일 수 있습니다.이 경우 new T()유효하지 않은 명령문입니다. new()제약은 말한다 T만드는 기본 생성자가 있어야합니다 new T()법률을.

일반적인 방법에 동일한 제약 조건을 적용 할 수 있습니다.

public static T GetObject<T>() where T : new()
{
    return new T();
}

매개 변수를 전달해야하는 경우 :

protected T GetObject(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}

2
고마워, 친구-오늘 배운 것이 기쁘다. 내 방법의 맥락에서, 나는 반사 솔루션으로 갔다. 건배!
한산

8
@nulliusinverba-흠 ... 질문에 메소드의 컨텍스트를 보여 주면 좋을 것입니다.
Alex Aza 2016 년

1
@ nulliusinverba-당신은 매개 변수가 필요하다는 질문에 표시하지 않았습니다.
Alex Aza 2016 년

1
S 업 투표를 당신을 위해 그러나 :) : - @ 알렉스 나는 그의 질문을 읽을 때 나는 그가 매개 변수를 원하지 않았다 가정

new (parameters) 제약과 같은 것을 사용할 수 있습니까?
Louis Rhys 2016 년


29

또 다른 방법은 리플렉션을 사용하는 것입니다.

protected T GetObject<T>(Type[] signature, object[] args)
{
    return (T)typeof(T).GetConstructor(signature).Invoke(args);
}

고맙습니다, 친구-나는 방법의 맥락 에서이 솔루션을 사용했습니다.
한산

22
참고로 FYI와 마찬가지로 Activator.CreateInstance (typeof (T), signature, args); 자세한 내용은 msdn.microsoft.com/en-us/library/4b0ww1we.aspx 를 참조 하십시오 .
Chris Baxter

@Calgary Coder : type [] 서명의 용도는 무엇입니까? 서명을 명시 적으로 지정하지 않고 매개 변수를 사용하여 CreateInstance를 직접 호출하면됩니다. 두 경우 모두 일치하는 생성자가 없으면 MissingMethodException이 발생합니다.
보리스 B.

4
이것이 당신에게 가장 적합한 답변이더라도, 그것은 분명히 지역 사회에 가장 적합한 것은 아닙니다. 이 질문을 찾는 사람들은 실제로 아래에서 답을 찾고 있습니다.
Trap

그리고 그 맥락은 정확히 무엇입니까? 원래 질문에 추가하십시오.
제임스

18

완성을 위해 여기에서 가장 좋은 해결책은 종종 팩토리 함수 인수를 요구하는 것입니다.

T GetObject<T>(Func<T> factory)
{  return factory(); }

이것을 다음과 같이 부릅니다.

string s = GetObject(() => "result");

이를 사용하여 필요한 경우 사용 가능한 매개 변수를 요구하거나 사용할 수 있습니다.


16

새로운 제약 조건은 괜찮지 만, 당신은 T가 너무 값 형식 인 필요로하는 경우, 이것을 사용 :

protected T GetObject() {
    if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
        return default(T);
    } else {
       return (T)Activator.CreateInstance(typeof(T));
    }
}

7

이것이 C # 4로 태그되어 있기 때문에 오픈 소스 프레임 워크 ImpromptuIntereface 에서는 생성자를 호출 할 때 dlr을 사용하여 생성자를 호출합니다. 생성자가 인수를 가질 때 Activator보다 훨씬 빠르며 그렇지 않은 경우 무시할 수있을 정도로 느립니다. 그러나 주요 장점은 C # 4.0 선택적 매개 변수를 사용하여 생성자가 처리하지 않는 생성자를 올바르게 처리한다는 것입니다.

protected T GetObject(params object[] args)
{
    return (T)Impromptu.InvokeConstructor(typeof(T), args);
}

4

이것을 얻으려면 다음 코드를 시도했습니다.

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.