I'm not really sure how to ask this question, but basically I want to know how to specify a class type generically such that I can type and paste code around.
For example I have the following code:
Public Class CustInfo
Implements INotifyPropertyChanged
Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Protected Sub NotifyPropertyChanged(ByVal Name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Name))
End Sub
Protected Sub NotifyPropertyChanged()
Dim myStackFrame As New StackFrame(1)
Dim myChangingPropertyName As String = myStackFrame.GetMethod.Name.Split("_")(1)
NotifyPropertyChanged(myChangingPropertyName)
End Sub
Protected Sub NotifyPropertyChanged(Of TResult)(propertyExpr As Expression(Of Func(Of CustInfo, TResult)))
NotifyPropertyChanged(Me.GetPropertySymbol(propertyExpr))
End Sub
The idea is to have the last Sub
be generic, that is to say, not specifically have to specify CustInfo in it's definition. This way I can literally copy this code to any other class and it will work unmodified.
I've tried creating a property that returns the type of the class and using that, which predictably failed. I tried using TypeOf, Me, even 'this' on a long shot and nothing worked. It seems there has to be a way for the compiler to know this based on this error message which I get when I change the last sub to:
Protected Sub NotifyPropertyChanged(Of TResult)(propertyExpr As Expression(Of Func(Of TResult)))
NotifyPropertyChanged(Me.GetPropertySymbol(propertyExpr))
End Sub
Data type(s) of the type parameter(s) in extension method 'Public Function GetPropertySymbol(Of TResult)(expr As System.Linq.Expressions.Expression(Of System.Func(Of CustInfo, TResult))) As String' defined in 'CustClasses.Extensions' cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
The extension method being referred to is:
<Extension()>
Public Function GetPropertySymbol(Of T, TResult)(obj As T, expr As Expression(Of Func(Of T, TResult))) As String
Return DirectCast(expr.Body, MemberExpression).Member.Name
End Function
So, as you can see the compiler correctly inferred what is going on, but still couldn't work with it. The only type that seems unknown is TResult, but that type should be easily inferred based on the other information in the extension method that is known.
It may be impossible to generically specify a class type in the procedure definition, in which case I'll modify the code every time I use it, but I'd rather not and learn something new in the process.