2009-10-23 3 views
3

값이있는 경우 값을 반환하는 int? (null 가능 정수),
을 사용하는 람다식이 있습니다. 그렇지 않으면 DBNull.Value입니다.일반 형식 매개 변수를 람다 식에 전달하는 방법은 무엇입니까?

Func<int?, object> getId = id => id.HasValue ? id.Value : (object)DBNull.Value; 

목표는 여기 그래서 여기, 내가 원하는 nullable 형식을 통과 할 수 있도록 약간 좀 더 일반적인 그 표현을 할 것을 DateTime?

입니다 내가 시작했다 이외의 기능 코드는 꺼져 있지만 확실하지 않음 은 nullable의 유형을 지정합니다.

int? imageId; 
DateTime? actionDate; 
Func<Nullable<T>, object> getValue = 
    id => id.HasValue ? id.Value : (object) DBNull.Value; 
SaveImage(getValue(imageId), getValue(actionDate)); 

는 제네릭 형식을 지정할 수 있습니다 또는 나는 그렇게 명명 된 함수를 작성해야합니까?

+2

일반적인 익명 메소드를 만들 수있는 방법이 없습니다. 이는 명목상의 방법으로 가장 잘 수행됩니다. –

답변

3

+0

나는 이것을 시도하고 그것을 작동, 내 질문의 요점이었다.하지만 나는 람다를 방법으로 변환하는 것을 거부했다. – Sung

+0

그건 그렇고, 내가 처음으로 'ReferenceEquals'를 사용한 적이 있습니다. 실제'Object' 메소드를 사용하는 것은 꽤 상쾌합니다. ;) – Sung

1

제네릭을 사용하는 대신 Object에서 확장 메서드를 사용하여 변환을 수행 할 수 있습니다.

다음은 샘플 프로그램입니다.

using System; 

static class Program 
{ 
    static object ToDbObject(this object value) 
    { 
     return value ?? DBNull.Value; 
    } 
    static void Main(string[] args) 
    { 
     int? imageId = 3; 
     DateTime? actionDate = null; 

     Console.WriteLine("ImageId {0}: [{1}] - {2}", imageId, imageId.ToDbObject(), imageId.ToDbObject().GetType()); 
     Console.WriteLine("actionDate {0}: [{1}] - {2}", actionDate, actionDate.ToDbObject(), actionDate.ToDbObject().GetType()); 
     Console.ReadKey(); 
    } 
} 

위의 인쇄 :

ImageId 3: [3] - System.Int32 
actionDate : [] - System.DBNull 

그것은 정확하게 두 경우 모두 처리 년대 ToDbObject 확장은 변환을 수행합니다.

public static Func<Nullable<T>, object> CreateGetValueFunc<T>() where T : struct 
{ 
    return id => id.HasValue ? id.Value : (object)DBNull.Value; 
} 

그리고이 같은 귀하의 예제에서 사용할 수 있습니다 :

SaveImage(
    CreateGetValueFunc<int>()(imageId), 
    CreateGetValueFunc<DateTime>()(actionDate)); 
1

나는 당신이 제네릭 형식 매개 변수를 지정할 수 있습니다 대리자 팩토리 메소드를 작성하여 그것을 할 수 있다고 생각 질문의 목적이 람다 표현식을 사용하기 때문에, 여기에 해결책이 있습니다. 제안 된 강력한 타이핑 대신 약한 타이핑을 사용하여 다른 경로를 취하지 만 동일한 목표를 달성합니다.

 // A lambda solution 
     Func<object, object> fnGetValue = 
      v => 
       ReferenceEquals(v, null) 
       ? DBNull.Value 
       : v; 


     // Sample usage 
     int? one = 1; 
     int? two = null; 
     object o1 = fnGetValue(one); // gets 1 
     object o2 = fnGetValue(two); // gets DBNull 

편집 : 람다 인수 V의 데이터 유형은 구조체 자체이며, nullable 형식 래퍼 없기 때문에이 느슨한 입력이 작동합니다. 분명히 호출자가 사용하는 Nullable 값은 lambda 인수에 도달하고 lambda 인수가 구조체 값 또는 null을 표시 할 때까지 해결되었거나 'unwrapped'되었습니다. Nullable 래퍼는이 시점에서 (또는 내가 찾을 수있는 한) 볼 수 없습니다. 이 동작은 v에서 람다에 디버그 중단 점을 넣고 그 값을 검사함으로써 증명할 수 있습니다. 이 동작의 좋은 부작용은 lambda가 Nullable 형식과 Nullable 형식 모두에 대해 똑같이 잘 작동한다는 것입니다.

+0

그것이 실제 함수로 싸여 있다면, 처음에는 람다를 사용하는 것이 문제가되지 않습니까? 함수의 내용은 비 λ 코드 일 수도 있습니다. –

+0

@jdk가 그의 코멘트에 맞습니다. 내 주요 목표는 익명의 함수/람다 식의 한계를 알아낼 수 있도록 새로운 함수를 만드는 데 집중하지 않고도 빠르고 & 더러운 표현식을 만드는 것이 었습니다. – Sung

관련 문제