Использование дженериков в интерфейсах

Краткое содержание ответа:

Да, плохие вещи могут и, вероятно, произойдут.

Для предотвращения этого сделайте:

free(myString);
myString = NULL;

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

Кроме того, вызов free() с NULL не приводит к каким-либо действиям. Для получения дополнительной информации см .: человек свободен

5
задан Daniel A. White 1 June 2009 в 23:15
поделиться

8 ответов

Похоже, у вас есть 3 варианта

Сделать ICookieService2 универсальным

public interface ICookieService2<T> : IDictionary<string, CookieData<T> {
...
}

Создать неуниверсальный базовый класс для CookieData и использовать его в интерфейсе

public interface ICookieData {}
public class CookieData<T>: ICookieData{}
public interface ICookieService2 : IDictionary<string, ICookieData> {}

Выберите конкретную реализацию

public interface ICookieService : IDictionary<string, CookieData<int>> {}
7
ответ дан 18 December 2019 в 12:01
поделиться

Вы также должны сделать ICookieService2 универсальным:

public interface ICookieService2<T>: IDictionary<string, CookieData<T>>
{
   // ...
}
4
ответ дан 18 December 2019 в 12:01
поделиться

Хорошо, вот что вы хотите:

public interface ICookieDataBase
{
    DateTime Expires { get; set; }
}

public struct CookieData<T> : ICookieDataBase
{
    public T Value { get; set; }
    public DateTime Expires { get; set; }
}

public class ICookieService : IDictionary<string, ICookieDataBase>
{
    // ...
}

public void DoWork()
{
    var intCookie =
        new CookieData<int> { Value = 27, Expires = DateTime.Now };

    var stringCookie =
        new CookieData<string> { Value = "Bob", Expires = DateTime.Now };

    ICookieService cs = GetICookieService();
    cs.Add(intCookie);
    cs.Add(stringCookie);
}
2
ответ дан 18 December 2019 в 12:01
поделиться

Для этого вам понадобится неуниверсальный интерфейс:

public interface ICookieData
{
  // you need this to get the value without knowing it's type
  object UntypedValue { get; }
  // whatever you need additionally ...
  Type DataType { get; } 

  DateTime Expires { get; set; }
}

public struct CookieData<T> : ICookieData
{
    // ICookieData implementation
    public object UntypedValue { get { return Value; } }
    public Type DataType { get { return typeof(T); } }
    public DateTime Expires { get; set; }

    // generic implementation
    T Value { get; set; }
}

public interface ICookieService2: IDictionary<string, ICookieData>
{
   // ...
}

CookieData<int> intCookie = { Value = 27, Expires = DateTime.Now };
CookieData<string> stringCookie = { Value = "Bob", Expires = DateTime.Now };

CookieService2 cs = new CookieService2();
cs.Add(intCookie);
cs.Add(stringCookie);
1
ответ дан 18 December 2019 в 12:01
поделиться

Я думаю, что вам нужно:

public interface ICookieService2<T>: IDictionary<string, CookieData<T>>
{
   // ...
}

в настоящее время ICookieService2 не является универсальным, поэтому T не определен.

Это позволяет вам создавать классы для реализации ICookieService2 или ICookieService2 и т. Д.

РЕДАКТИРОВАТЬ: Отвечая на ваш последний запрос, я думаю, это действительно зависит от того, что именно вам нужно. Однако что-то подобное может сработать для вас.

public interface ICookieData
{
    object Value {get;} // if you need to be able to set from CookieService, life gets harder, but still doable.
    DateTime Expires {get;}
}

public struct CookieDate<T> : ICookieData
{
    T Value {get;set;}
    DateTime Expires {get;set;}

    object ICookieData.Value
    {
        get
        {
            return Value;
        }
    }
}

Тогда CookieService может быть или иметь список, и вы сможете добавить как CookieData, так и CookieData. Если вам нужно писать (устанавливать) из CookieService, это немного сложнее и, возможно, лучше не использовать дженерики. Но если вам просто нужно иметь возможность получить CookieData, это может сработать для вас.

1
ответ дан 18 December 2019 в 12:01
поделиться

не уверен насчет C #, но способ Java заключался бы в том, чтобы также объявить ваш ICookieService2 с параметром или указать к чему-то конкретному в CookieData .

0
ответ дан 18 December 2019 в 12:01
поделиться

Вы можете попробовать

public struct CookieData<T>
    where T : Object
{
    T Value { get; set; }
    DateTime Expires { get; set; }
}

Таким образом, все экземпляры T будет вынужден иметь базовый тип Object. (почти все в C # (например, int == System.Integer и т. д.).

0
ответ дан 18 December 2019 в 12:01
поделиться

If I understand your question correctly you are wanting to treat the generic types like they are the same, but in current .NET implementation you can't do this.

CookieData can't be passed as a CookieData they are actually different types, the generic types are not related and can't be cast or passed like they are the same. Creating ICookieService2 as an open generic (meaning ICookieService2) doesn't solve the problem because then you would have a different ICookieService2 type for every different type and all of them would be in a different dictionary.

You can create a ICookieData interface and implement it in CookieData and use ICookieData to store the items in the dictionary (as Stefan has already suggested).

You can do what you want in C# 4.0 (with a few restrictions). There is an article about it here until then, you have to pass it as a non-generic type that is common to them such as an interface or just have the value parameter be an object on the dictionary because you are going to have to case it to use it anyway if you are using primitives as the type arguments.

0
ответ дан 18 December 2019 в 12:01
поделиться
Другие вопросы по тегам:

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