开发者

invoking delegate with generics arguments in c#

开发者 https://www.devze.com 2022-12-10 11:11 出处:网络
I have a class: public class MyClass<T> { public string TestProperty { get; set; } } and I want to create a delegate to run on instances of this class, such as:

I have a class:

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

and I want to create a delegate to run on instances of this class, such as:

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

However, the above delegate can't be invoked with anything other than a MyClass<object>, such as MyClass<DateTime> or MyClass<string>.

How can I either define the delegate, or modify the delegate so that I can execute the delegate on a MyClass<T> where T is anything which extends object?

Edit: This can wait until C# 4 if thats when this becomes possible (if so, please still tell me how) although i'd prefer to get on with it now in 3.5

Edit: I actually also have a 2nd class:

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

Ideally id like to use开发者_JS百科 the following syntax to define some delegates:

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

Then given an object, id like to see which delegate arguments match, and then run them

Is this possible? What alternatives do I have to create such delegates?

Thanks


EDIT: After thinking about it a bit further, I don't believe C# 4 will actually help you in this case. You'd need the MyClass type itself to be variant, but it can't be because it's a class. However...

You could write a generic method to return you a specific action:

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

EDIT: I should have mentioned Andrew Hare's suggestion before - but here's another alternative using a base class instead of an interface.

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

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

Then use Action<MyClass>.


You could create an interface to encapsulate the members of MyClass<T> that you need:

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

Then change your delegate to use that interface:

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

Edit: And obviously you would need to do this as well:

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


I know this is an old post, but I figured it will help the next person who might want to do this. I tinkered with this idea a bit because I find it to be a very desirable feature. I got delegates that have a generic parameter to work by doing the following:

 

 

    public delegate void AppSettingsHandlerMethodSetKeyValue(string key, T value);

    public class AppSettingsHandler

    {

        public CacheHandler(AppSettingsHandlerMethodSetKeyValue setAppSettingsVariable)

        {

            SetApplicationSettingsVariable = (AppSettingsHandlerMethodSetKeyValue)setAppSettingsVariable;

        }

 

        internal AppSettingsHandlerMethodSetKeyValue SetApplicationSettingsVariable { get; set; }

   

        internal void SetApplicationSetting(string key, T value)

        {

            SetApplicationSettingsVariable(key, value);

        }

    }

 

 

I hope someone finds this helpful. I'm sure someone will have something to say about it, but it works for me.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号