Generic과 params의 혼용

안녕하세요.
항상 눈팅만 하다가 궁금한게 생겨 이렇게 글 남깁니다. ㅎㅎ
(항상 좋은내용들 소개해주시고 알려주셔서 감사합니다.)

질문은 다음과 같습니다. (제목이 참 애매하네요,)

generic으로 배열을 받고, 해당 배열을 params 를 사용하는 함수로 넘기려 하였는데, 이상하게 아래 사진처럼 들어옵니다.

image

아래는 간단히 구성한 예제입니다.
자세한 내용은 주석에 작성해 두었습니다.

public class Main
{
    public class Main()
    {
        var testClass = new TestClass<SomeClass, object[]>();

        // 이상하게 작동
        testClass.MainFunc(new object[] { "str1", "str2" });

        // 정상작동
        testClass.MainFunc2(new object[] { "str1", "str2" });
    }
}


public class TestClass<TEntity, TKey>
    where TEntity : class
{
    public void MainFunc(TKey key)
    {
        TestFunc(key);
    }

    public void MainFunc2(object[] objectArray)
    {
        TestFunc(key);
    }

    public void TestFunc(params object[] objectArray)
    {
        //  MainFunc의 경우 여기서 objectArray의 Length가 2가 아닌 1이고, 2차원 배열이 들어옵니다.
        // 어떻게 해야 Length가 2인 배열값을 얻을 수 있을까요?
        // 또한 어떤 원리에 의해 이런일이 발생하는 것일까요?
    }
}

감사합니다.

1개의 좋아요
    public void MainFunc(TKey key)
    {
        TestFunc(key);
    }

대신,

    public void MainFunc(TKey[] key)
    {
        TestFunc(key);
    }

하셔야 합니다.

1개의 좋아요

빠른 답변 감사합니다 dimohy님.

하지만 아래 코드처럼 변경해보아도 동일한 현상이 발생합니다.

혹시 제가 착각한 부분이 있을까요?

public class Main
{
    public class Main()
    {
        var testClass = new TestClass<SomeClass, object>();

        testClass.MainFunc(new object[] { "str1", "str2" });
    }
}


public class TestClass<TEntity, TKey>
    where TEntity : class
{
    public void MainFunc(TKey[] key)
    {
        TestFunc(key);
    }


    public void TestFunc(params object[] objectArray)
    {

    }
}
1개의 좋아요

아닙니다. 제가 테스트 코드로 검증하지 않아 생긴 문제입니다.

TKey[] key 역시 object[]가 아닌 TKey[]이고 object이므로 첫번째 인자로 들어가는게 맞습니다. 이를 해결하려면 object[] 로 캐스팅 해야 하는데요,

Testfunc(key.Cast<object>().ToArray());

TestFunc가 object[] 대신 TKey[]를 받을 수 있다면 굳이 캐스팅 할 필요는 없을 것 같습니다.

public void TestFunc(params TKey[] objectArray)
{

}
2개의 좋아요
where ..., TKey: class

을 하셔도 됩니다.

1개의 좋아요

이해를 돕기위해 TestFunc으로 표현하였지만 사실 TestFunc는 외부 라이브러리라 해당 함수 수정은 힘들 것 같습니다.

key.Cast().ToArray() 를 사용하여야 할 것 같네요.

(where …, TKey: class는 해당 클래스를 사용하는 다른 객체 때문에 사용이 불가능하고요.)

친절한 답변 정말 감사드립니다!

2개의 좋아요