Различие между неявным и явным созданием делегата (с и без дженериков)

Здесь вы, JSON, были искажены недействительными символами. Используйте функцию поиска по клавишам

let obj = {
  "barID1": {
    "address": "4 East Terrace, Sydney NSW 2000",
    "appStoreURL": "http://itunes.apple.com/app/idXXXXXXXXX",
    "description": "description text",
    "imgURLs": [ "Https:url1",  "https:url2", "https:url3" ],
    "lat": -34.810585,
    "lon": 138.616739,
    "name": "Africola",
    "phone": "(08) 8223 3885",
    "status": "active",
    "venueImgURL": "https:url"
  },
  "barID2": {
    "address": "138/140 Gouger St, Sydney NSW 2000",
    "appStoreURL": "http://itunes.apple.com/app/idXXXXXXXXX",
     "description": "description text",
    "imgURLs": [ "Https:url1",  "https:url2", "https:url3" ],
    "lat": -34.848082,
    "lon": 138.599813,
    "name": "Disco Mexico Taqueria",
    "phone": "0416 855 108",
    "status": "active",
    "venueImgURL": "https:url"
  }
};

let result = Object.keys(obj).find(key => obj[key].name === "Africola");
console.log(result);

Как функцию:

let obj = {
  "barID1": {
    "address": "4 East Terrace, Sydney NSW 2000",
    "appStoreURL": "http://itunes.apple.com/app/idXXXXXXXXX",
    "description": "description text",
    "imgURLs": [ "Https:url1",  "https:url2", "https:url3" ],
    "lat": -34.810585,
    "lon": 138.616739,
    "name": "Africola",
    "phone": "(08) 8223 3885",
    "status": "active",
    "venueImgURL": "https:url"
  },
  "barID2": {
    "address": "138/140 Gouger St, Sydney NSW 2000",
    "appStoreURL": "http://itunes.apple.com/app/idXXXXXXXXX",
     "description": "description text",
    "imgURLs": [ "Https:url1",  "https:url2", "https:url3" ],
    "lat": -34.848082,
    "lon": 138.599813,
    "name": "Disco Mexico Taqueria",
    "phone": "0416 855 108",
    "status": "active",
    "venueImgURL": "https:url"
  }
};

const findKeyByName = (obj, search) => Object.keys(obj).find(key => obj[key].name === search);

console.log(findKeyByName(obj, 'Africola'));
console.log(findKeyByName(obj,'Disco Mexico Taqueria'));

5
задан Nathan Ridley 14 May 2009 в 14:35
поделиться

2 ответа

Нет никакой разницы между MyAction и новое действие (MyAction) (когда они оба действительны), кроме первого, не будет работать в C # 1. Это неявное преобразование группы методов . Бывают случаи, когда это неприменимо, особенно когда компилятор не может определить, какой тип делегата вам нужен, например

Delegate foo = new Action(MyAction); // Fine
Delegate bar = MyAction; // Nope, can't tell target type

Это входит в игру в вашем вопросе, потому что оба задействованных метода перегружены. В основном это приводит к головной боли.

Что касается дженериков - это интересно. Группы методов не получают особой любви от вывода типов C # 3 - я не уверен, будет ли это улучшено в C # 4 или нет. Если вы вызываете универсальный метод и указываете аргумент типа, Вывод типа работает довольно хорошо, но если вы попытаетесь сделать это наоборот, он потерпит неудачу:

using System;

class Test
{
    static void Main()
    {
        // Valid - it infers Foo<int>
        DoSomething<int>(Foo);
        // Valid - both are specified
        DoSomething<int>(Foo<int>);
        // Invalid - type inference fails
        DoSomething(Foo<int>);
        // Invalid - mismatched types, basically
        DoSomething<int>(Foo<string>);
    }

    static void Foo<T>(T input)
    {
    }

    static void DoSomething<T>(Action<T> action)
    {
        Console.WriteLine(typeof(T));
    }
}

Вывод типа в C # 3 очень сложен и в большинстве случаев работает хорошо (в частности, отлично подходит для LINQ), но не работает в несколько других. В идеальном мире было бы легче понять и более мощный в будущих версиях ... посмотрим!

14
ответ дан 18 December 2019 в 09:10
поделиться

Неуниверсальное неявное создание делегата - это просто синтаксический сахар, поэтому компилятор генерирует точно такой же код для

DoSomething(MyAction);

и

DoSomething(new Action(MyAction));

, поскольку он может вывести тип делегата непосредственно из аргументы метода и контекст.

С универсальным делегатом вы должны указать тип делегата из-за ковариации и контравариантности (см. http://msdn.microsoft.com/en-us/library/ms173174 (VS. 80) .aspx для подробностей) - T in Action может быть надтипом T в методе, и он все равно будет приниматься как метод делегата. Итак, вам нужно явно указать T в делегате, поскольку компилятор не может это понять сам.

3
ответ дан 18 December 2019 в 09:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: