문제

C#에서 내 자신의 연기 실행 메커니즘을 어떻게 구현할 수 있습니까?

예를 들어, 나는 다음과 같습니다.

string x = DoFoo();

x를 "사용"할 때까지 Dofoo가 실행되지 않도록 마법을 수행 할 수 있습니까?

도움이 되었습니까?

해결책

Lambdas/Delegates를 사용할 수 있습니다.

Func<string> doit = () => DoFoo();
//  - or -
Func<string> doit = DoFoo;

나중에 호출 할 수 있습니다 doit 방법처럼 :

string x = doit();

나는 당신이 얻을 수있는 가장 가까운 것이 다음과 같습니다.

Lazy<string> x = DoFoo;

string y = x; // "use" x

정의와 함께 Lazy<T> 이것과 비슷합니다 (테스트되지 않은) :

public class Lazy<T>
{
    private readonly Func<T> func;
    private bool hasValue;
    private T value;

    public Lazy(Func<T> func)
    {
        this.func = func;
        this.hasValue = false;
    }

    public static implicit operator Lazy<T>(Func<T> func)
    {
        return new Lazy<T>(func);
    }

    public static implicit operator T(Lazy<T> lazy)
    {
        if (!lazy.hasValue)
        {
            lazy.value = lazy.func();
            lazy.hasValue = true;
        }
        return lazy.value;
    }
}

불행히도, 컴파일러의 유형 추론 알고리즘은 Func<T> 따라서 암시 적 변환 연산자와 일치시킬 수 없습니다. 우리는 대의원의 유형을 명시 적으로 선언해야합니다.

// none of these will compile...
Lazy<string> x = DoFoo;
Lazy<string> y = () => DoFoo();
Lazy<string> z = delegate() { return DoFoo(); };

// these all work...
Lazy<string> a = (Func<string>)DoFoo;
Lazy<string> b = (Func<string>)(() => DoFoo());
Lazy<string> c = new Func<string>(DoFoo);
Lazy<string> d = new Func<string>(() => DoFoo());
Lazy<string> e = new Lazy<string>(DoFoo);
Lazy<string> f = new Lazy<string>(() => DoFoo);

다른 팁

한 가지 옵션은 Lazy<T> Class, 이전에는 Parallel Extensions 라이브러리에서 이제 .NET Framework 4.0의 일부가되었습니다.

스레드 인식 방식으로 프로세스 데이터를 지연시킬 수 있습니다.

다소 더러워 지지만 항상 수율 키워드를 사용할 수 있습니다.

public IEnumerable<int> DoFoo() {
   Console.WriteLine("doing foo");
   yield return 10;
}

[Test]
public void TestMethod()
{
    var x = DoFoo();
    Console.WriteLine("foo aquired?");
    Console.WriteLine(x.First());
}

문자열을 통과하는 대신 엑스, 당신에게 문자열을 조달하는 대의원을 통과하십시오

Func<String> fooFunc=()=>DoFoo();

원할 때까지 'dofoo ()'에게 전화하지 않는 이유는 무엇입니까?

-- 편집하다

내 말은, "사용"은 무엇을 의미합니까?

예를 들어, '.toString ()'호출 될 때 호출되기를 원한다면 항상 클래스를 상속하고 기능을 구현할 수 있습니다 (그러나 이것은 직관적이지 않은 IMHO입니다).

당신은 LINQ를 실제로 설명합니다. LINQ 쿼리는 데이터를 얻는 방법을 설명하지만 쿼리가 반복 될 때만 데이터가 검색됩니다 (DOFUNC가 호출됩니다). 디자인을 수락하도록 변경할 수 있는지 고려하십시오 IQueryable<string> 필요한 곳 string.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top