2012-07-03 2 views
60

요청을 받아 응답을 제공하는 일반적인 방법이 있습니다.C# 제네릭에 void가 있습니까?

public Tres DoSomething<Tres, Treq>(Tres response, Treq request) 
{/*stuff*/} 

하지만 항상 내 요청에 대한 응답을 원하지는 않으며 응답을 받기 위해 요청 데이터를 항상 제공하고 싶지는 않습니다. 또한 사소한 변경을하기 위해 메서드를 복사하여 붙여 넣기를하고 싶지 않습니다. 내가 원했던 것은 이것을 할 수있는 것입니다 :

public Tre DoSomething<Tres>(Tres response) 
{ 
    return DoSomething<Tres, void>(response, null); 
} 

어떤 방식으로 이것을 실현할 수 있습니까? 특별히 무효를 사용하는 것이 효과가없는 것 같지만 비슷한 것을 찾으려고합니다.

+1

왜 그냥하는 System.Object를 사용 해봐요 (트레스 응답, Treq 요청)에 널 (null) 검사를합니까? – James

+0

반환 값을 사용해야 함을 유의하십시오. 프로 시저와 같은 함수를 호출 할 수 있습니다. '해봐요 (x)는, '대신 Y'의 = 해봐요 (x)는, '가 –

답변

61

당신은 void를 사용할 수 없지만 object을 사용할 수 있습니다 : 당신의 것-BE- void 기능 null를 반환해야하기 때문에 조금 불편하지만, 그것은 당신의 코드를 통합하는 경우, 지불하는 작은 가격이어야한다.

반환 유형은 적어도 부분적으로 일반 대표의 Func<...>Action<...> 가족 사이의 분할에 대한 책임으로 void를 사용하는이 무능력 : 모든 Action<X,Y,Z> 단순히 Func<X,Y,Z,void> 될 것, void를 반환 할 수 있었다. 불행히도 이것은 불가능합니다.

+26

** (농담) **는 그가 여전히 함께 그-될 보이드 방법에서'void'를 반환 할 수'System.Runtime를 반환한다. Serialization.FormatterServices.GetUninitializedObject (typeof (void));'. 그것은 박스형 공허가 될 것이다. –

1

void 유형은 메소드의 리턴 유형으로 만 유효합니다.

void의 제한 사항을 해결할 방법이 없습니다.

61

아니요, 불행히도 아닙니다. void이 "진짜"유형 (예 : unit in F#) 인 경우 수명이 여러면에서 훨씬 더 간단합니다. 특히, 우리는 모두 Func<T>Action<T> 가족을 필요가 없을 것 - 단지 Func<void> 대신 Action, Func<T, void> 대신 Action<T>이있을 거라고하는 등 또한 비동기 만들 것

간단 - 필요가 없을 것 비 일반형 Task 유형 - 우리는 단지 Task<void> 일 것입니다.

불행하게도, 그것은 다른 사람이 제안대로 단순히 Object를 사용할 수있는 C# 또는 .NET 형식 시스템의 작업 방식 ...

+4

는'불행하게도, 그 당신은 어쩌면 일이 결국 그런 식으로 작동 할 수 있음을 나 희망하고 있었다'...는 C# 또는 .NET 타입 시스템이 작동하는 방식이 아니다. 당신의 마지막 요점은 우리가 그런 식으로 일할 가능성이 없다는 것을 의미합니까? –

+2

@Sahuagin : 나는이 시점에서 꽤 큰 변화가 될 것이라고 생각하지 않는다. –

+0

null을 참조로 허용하는 것과 같이 void를 형식으로 허용합니까? 또 다른 10 억 달러 실수? – stannius

13

아니다. 또는 Int32 나는 약간의 사용을 보았다. Int32을 사용하면 "더미"숫자가 사용되지만 (0 사용) 적어도 크고 이국적인 객체는 Int32 참조에 넣을 수 없습니다 (구조체는 봉인되어 있음).

public sealed class MyVoid 
{ 
    MyVoid() 
    { 
    throw new InvalidOperationException("Don't instantiate MyVoid."); 
    } 
} 

MyVoid 참조가 허용됩니다 (이 정적 클래스 아니다) 만 null가 될 수 있습니다

당신은 또한 당신이 "무효"유형을 소유 작성할 수 있습니다. 인스턴스 생성자는 private입니다. 누군가가 리플렉션을 통해이 개인 생성자를 호출하려고하면 예외가 발생합니다.

+2

다른 이름은 null 객체 패턴 (디자인 패턴)입니다. – Aelphaeis

18

다음은 수행 할 수있는 작업입니다. @ JohnSkeet이 C#에는 단위 유형이 없다고 했으므로 직접 작성하십시오!

public sealed class ThankYou { 
    private ThankYou() { } 
    private readonly static ThankYou bye = new ThankYou(); 
    public static ThankYou Bye { get { return bye; } } 
} 

지금 당신은 항상 대신 Action<...>

public ThankYou MethodWithNoResult() { 
    /* do things */ 
    return ThankYou.Bye; 
} 

Func<..., ThankYou>를 사용하거나 이미 수신 팀에 의해 만들어진 것을 사용할 수 있습니다 http://msdn.microsoft.com/en-us/library/system.reactive.unit%28v=VS.103%29.aspx

+0

System.Reactive.Unit은 좋은 제안입니다. 당신이 패키지 관리자를 nuget 사용, 단위 클래스 이외를 사용하지 않기 때문에 년 11 월 2016, 당신의 경우는, 가능한 한 반응성 프레임 워크의 조각을 작은 점점 관심이'설치 - 패키지 System.Reactive.Core' – DannyMeister

1

내가 위의 알렉세이 코프에 의해 아이디어를 좋아하지을하지만, 수 조금 간소화 될 것이다

public sealed class Nothing { 
    public static Nothing AtAll { get { return null; } } 
} 

나는 다만 널

같은 생각 (또는 Jeppe의 Stig 닐슨에 의해 하나)을 얻었다 또한 입력 된 클래스와 사용에 대한 대단한 없습니다 Nothing.AtAll 왜 명백한 이유가 없습니다.

예. 형식이 특정 메서드에 대한 인수로 전달 된 프로 시저/함수에 대한 설명을 설명하는 데만 사용되며 자체적으로 인수를 사용하지 않는 경우

(당신은 여전히 ​​더미 래퍼를 만들기 위해 하나 또는 선택 사양 인 "아무것도"을 허용하지해야합니다. 그러나 클래스의 사용은 myClass가 < 아무것도>로 좋은 모습 IMHO)

void myProcWithNoArguments(Nothing Dummy){ 
    myProcWithNoArguments(){ 
} 

또는

void myProcWithNoArguments(Nothing Dummy=null){ 
    ... 
} 
+0

'null'값은 '객체'가 없거나 없음을 의미합니다. 'Nothing '에 대한 하나의 값을 가짐으로써 결코 다른 것처럼 보이지 않는다는 것을 의미합니다. – LexieHankins

관련 문제