I need to have a interface that has generic methods. However each implementation of that interface will know its type.
class Program
{
static void Main(string[] args)
{
var specificContext = new SpecificContext();
var res = new SrvThatCantBeGeneric().GetValueFromSpecificContext(specificContext);
Console.WriteLine(res);
}
}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)
{
return specificContext.MyProperty; // <-- this is where it breaks
}
}
public interface ISrvThatCantBeGeneric
{
int GetValueFromSpecificContext<T>( T specificContext);
}
public class SpecificContext
{
public int MyProperty { get; set; } = 42;
}
For some reason when I do it the above way it doesn't work and states that:
'SpecificContext' does not contain a definition for 'MyProperty' and no accessible extension method 'MyProperty' accepting a first argument of type 'SpecificContext' could be found (are you missing a using directive or an assembly reference?)
Why is this happening and how to solve it?
I can fix it by moving definition of generic type like so:
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric<SpecificContext>
{
public int GetValueFromSpecificContext(SpecificContext specificContext)
{
return specificContext.MyProperty; // <-- this is where it breaks
}
}
public interface ISrvThatCantBeGeneric<T>
{
int GetValueFromSpecificContext( T specificContext);
}
but this breaks in another parts of code and is no go.
Edit: Simplification of my code
By writing:
public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)
You "override" the scope and here SpecificContext
is a generic type parameter that masks the class having this name, so it is the same as:
public int GetValueFromSpecificContext<T>(T specificContext)
Perhaps you wanted to write:
public interface ISrvThatCantBeGeneric
{
int GetValueFromSpecificContext<T>(T specificContext) where T : SpecificContext;
}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
public int GetValueFromSpecificContext<T>(T specificContext) where T : SpecificContext
{
return specificContext.MyProperty;
}
}
public class SpecificContext
{
public int MyProperty { get; set; } = 42;
}
public class SpecificContextChild : SpecificContext
{
public SpecificContextChild()
{
MyProperty = 10;
}
}
Test
var server = new SrvThatCantBeGeneric();
var context = new SpecificContextChild();
Console.WriteLine(server.GetValueFromSpecificContext(context));
Output
10
Also you can promote interface and class as generics, and not the method itself
In case it is relevant:
public interface ISrvThatCantBeGeneric<T> where T : SpecificContext
{
int GetValueFromSpecificContext(T specificContext);
}
public class SrvThatCantBeGeneric<T> : ISrvThatCantBeGeneric<T> where T : SpecificContext
{
public int GetValueFromSpecificContext(T specificContext)
{
return specificContext.MyProperty;
}
}
public class SpecificContext
{
public int MyProperty { get; set; } = 42;
}
public class SpecificContextChild : SpecificContext
{
public SpecificContextChild()
{
MyProperty = 10;
}
}
var server = new SrvThatCantBeGeneric<SpecificContextChild>();
var context = new SpecificContextChild();
Console.WriteLine(server.GetValueFromSpecificContext(context));
Also if you prefer or need you can use an interface instead of the base class
public interface IContext
{
int MyProperty { get; set; }
}
Non-generic class version:
public interface ISrvThatCantBeGeneric
{
int GetValueFromSpecificContext<T>(T specificContext) where T : IContext;
}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
public int GetValueFromSpecificContext<T>(T specificContext) where T : IContext
{
return specificContext.MyProperty;
}
}
public class SpecificContext : IContext
{
public int MyProperty { get; set; } = 42;
}
Generic class version:
public interface ISrvThatCantBeGeneric<T> where T : IContext
{
int GetValueFromSpecificContext(T specificContext);
}
public class SrvThatCantBeGeneric<T> : ISrvThatCantBeGeneric<T> where T : IContext
{
public int GetValueFromSpecificContext(T specificContext)
{
return specificContext.MyProperty;
}
}
public class SpecificContext : IContext
{
public int MyProperty { get; set; } = 42;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.