2009-11-05 2 views
1

У меня есть класс:вызова делегата с дженериков аргументами в C#

public class MyClass<T> 
{ 
    public string TestProperty { get; set; } 
} 

и я хочу создать делегат для запуска на экземпляры этого класса, таких как:

Action<MyClass<object>> myDelegate = myclass => myclass.TestProperty = "hello"; 

Однако, над делегатом не может быть вызвано ничего, кроме MyClass<object>, например MyClass<DateTime> или MyClass<string>.

Как я могу определить делегат или изменить делегат, чтобы я мог выполнить делегат на MyClass<T>, где T - это что-нибудь, что расширяет object?

Edit: Это может ждать до C# 4, если тот, когда это становится возможным (если это так, пожалуйста, еще скажите мне, как), хотя я бы предпочел, чтобы с ней сейчас в 3,5

Edit: я на самом деле также есть 2-й класс:

public class MyDerivedClass<T1, T2> : MyClass<T1> 
{ 
    public int OtherProp { get; set; } 
} 

в идеале ид нравится использовать следующий синтаксис для определения некоторых делегатов:

CreateDelegate<MyClass<object>>(mc => mc.TestProperty = "hello"); 
CreateDelegate<MyDerivedClass<object, object>>(mc => mc.OtherProp = 4); 

Затем данный объект, ид нравится видеть, которые делегируют аргументы совпадают, а затем запустить их

Возможно ли это? Какие альтернативы мне нужны для создания таких делегатов?

Благодаря

ответ

3

Вы можете создать интерфейс для инкапсуляции членов MyClass<T>, что вам нужно:

interface IFoo 
{ 
    String TestProperty { get; set; } 
} 

Затем измените свой делегат использовать этот интерфейс:

Action<IFoo> myDelegate = myclass => myclass.TestProperty = "hello"; 

Edit: И, очевидно, вы бы необходимо также это сделать:

public class MyClass<T> : IFoo 
{ 
    public String TestProperty { get; set; } 
} 
+0

спасибо за помощь, см. Мой комментарий @Tony и обновленный вопрос –

+0

интерфейсы были ответом, просто нужно было перестать быть глупым! –

4

EDIT: Подумав немного дальше, я не верю C# 4 будет на самом деле помочь вам в этом случае. Вам нужно, чтобы тип MyClass был вариантом, но это не может быть потому, что это класс. Однако ...

Вы можете написать общий метод вернет вам конкретные действия:

public Action<MyClass<T>> NewTestPropertyDelegate<T>() 
{ 
    return myclass => myclass.TestProperty = "hello"; 
} 

EDIT: Я хотел бы упомянуть предложение Эндрю Hare перед - но вот еще одна альтернатива с использованием базового класса вместо интерфейс.

public abstract class MyClass 
{ 
    public string TestProperty { get; set; } 
} 

public class MyClass<T> : MyClass 
{ 
    ... 
} 

Затем используйте Action<MyClass>.

+0

Хмм спасибо за информацию, похоже, что им будет не повезло. ive обновил вопрос немного больше информации, думаю, я могу немного ввести вас в заблуждение, упростив проблему :( –

+0

Могу я не использовать выражение > вместо этого, а затем изменить выражение на правильное значение Т, когда оно применимо? –

+0

@ Андрю: Хм ... возможно. Не уверен. Я постараюсь не забыть еще раз взглянуть на это позже. –

0

Я знаю, что это старый пост, но я решил, что это поможет следующему человеку, который может это сделать.Я немного потрудился с этой идеей, потому что считаю ее очень желательной особенностью. Я получил делегат, которые имеют общий параметр для работы, выполнив следующие действия:

общественного делегат недействительного AppSettingsHandlerMethodSetKeyValue (строка ключ, значение Т);

общественного класса AppSettingsHandler

{

общественного CacheHandler (AppSettingsHandlerMethodSetKeyValue setAppSettingsVariable)

{

SetApplicationSettingsVariable = (AppSettingsHandlerMethodSetKeyValue) setAppSettingsVariable;

}

внутренний AppSettingsHandlerMethodSetKeyValue SetApplicationSettingsVariable {получить; задавать; }

внутренних пустот SetApplicationSetting (строка ключа, значение Т)

{

SetApplicationSettingsVariable (ключ, значение);

}

}

Я надеюсь, что кто-то считает это полезным. Я уверен, что у кого-то есть что сказать об этом, но это работает для меня.

Смежные вопросы