Implementing a specific case of a generic, versus deriving from it - c#

I am trying to write out a specific case of a generic class with additional functionality, but I am not sure why the following happens.
Suppose I have a generic class:
class Generic<T>
{
protected T value;
}
If I write out a specific implementation, I can't actually use the specific type I've narrowed it down to:
EDIT: I goofed up, this doesn't work.
class Generic<float>
{
// This doesn't work
public void Add()
{
value + 1.0f;
}
}
But if I inherit from the specific version, it does work:
class Specific : Generic<float>
{
// This does work
public void Add()
{
value + 1.0f;
}
}

In case someone is still reading this, I wanted to point out that this seems to be possible with extension methods:
class Generic<T>
{
public T value;
}
static class Extension
{
public static void Add (this Generic<float> generic)
{
generic.value += 1.0f;
}
}
The downside seems to be that 'value' has to be public or internal.

Your first attempt simply isn't a valid declaration - the part that specifies a class can't specify any type arguments.
If you think about it, how would the CLR know whether or not there was a specialized type available? What would it do if there were two different specializations of the same generic type in two loaded assemblies? It would have to check all the referenced assemblies any time a particular type argument combination was used for the first time. (This couldn't be done at compile-time, as other classes may just be referring to Generic<T>.)
In many cases you can use values of the type in ways which are meaningful to the type using constraints. For example, if you constrain T with where T : IComparable<T> then you can compare any two T values using Compare. Unfortunately there's no way of representing arithmetic operators in this way, although you may want to look at Marc Gravell's generic operator work in MiscUtil.
While I feel your pain, there's simply nothing like this in .NET generics - you'll want to think of alternative designs for whatever problem you're really trying to solve.

in this case :
class Generic<float>
{
// This doesn't work
public void Add()
{
value + 1.0f;
}
}
It doesn't mean that you are working with a Generic class using float as its generic type but it means that the name of the generic type is "float" in the source (instead of using T you are using "float" as its name ) Thus there's no conversion to float.In other words you are using a generic notation as a template that can be substituted with real types later (but not in the template itself and that's why in C++ they are called templates)
In this code :
class Specific : Generic<float>
{
// This does work
public void Add()
{
value + 1.0f;
}
}
you are telling the compiler that you want the specific class be a child of a generic class while it's template type will be replaced by type float.

Generic types are used for arithmetic reusability. That is, you must write something common between all possible Ts in your code.
class Generic<T>
{
protected T value; //it's valid to declare a member whose type is T
public void Add()
{
value + 1.0f; //invalid, because not all T are allowed to add
//with 0.1f by default
//consider T is the type Person
}
public void Print()
{
Type t = typeof(T); //valid, for all T we can get its type
}
}
And when you specified some T (e.g. float in your question), the compiler knows the T is float, so it's valid to add 0.1f to it.

I also looked for similar solution, I think you also got this thinking from ADA or such programming language.
But, as others wrote, making type specific class definition is not generic programming, it's specialization, so the simpliest (and only in C#) way is to create a specified class, based on generic structure:
class Generic<T>
{
protected T value;
public Generic(T val)
{
value = val;
}
}
class Generic_float : Generic<float>
{
public Generic_float(float val)
: base(val)
{
}
public void Add()
{
value = value + 1.0f;
}
}
As you can see, we created a class for the specified case, having the extra ability of extending the structure with fields and methods. This advantage is very good to refine behavior of our objects, and gives ability of implicit cast of the typed generic class to our customized one (with the notice that casting back is not possible):
public void Test()
{
Generic<float> var1 = new Generic<float>(1.5f);
Generic_float var2 = new Generic_float(2.5f);
var1 = var2; // Works, var links to var2's memory field casted as Generic<float>
var2 = var1; // cannot implicitly convert error, if want to use then have to make explicit conversion
}
Don't know if the way you expected should work in languages like C# or other managed ones, but maybe this workaround gives you what you really wanted to get.

Related

Implicit conversion not assignable to interface

I have a class with an implicit conversion from string defined as:
class TestClass : ITestInterface
{
public static implicit operator TestClass(string value)
{
return new TestClass(value);
}
public TestClass(string value)
{
Value = value;
}
public string Value { get; set; }
}
It implements a marker interface:
public interface ITestInterface { }
I have a method of another class defined as:
public void DoSomething(ITestInterface thing) { }
I'm getting an error trying to call that method:
public void Test()
{
TestClass a = "This works fine.";
DoSomething("Why doesn't this work?");
}
cannot convert from 'string' to 'Tests.ITestInterface'
All code is greatly simplified; my actually requirements are far more complex, but this seems to be the core of what is blocking the pattern I'd like to implement.
What is preventing this from working? (Something in the C# spec?)
Are there any changes I can make to my code to allow this type of casting to work?
You're omitting the third option that explains the issue:
//1
TestClass a = "This works fine.";
//2
ITestInterface i = "This doesn't work either!";
//3
DoSomething("Why doesn't this work?");
In (1), you've declared TestClass a. This means that the compiler knows that when you use a different type (string, in this case), that it should try to convert said value to TestClass.
In (2), you've declared ITestInterface i. This means that the compiler knows that when you use a different type (string, in this case), that it should try to convert said value to ITestInterface.
That is the source of the problem. There is no conversion defined between string and ITestInterface.
What you're currently thinking is:
Well, I know that I want this to be converted to a TestClass. Why doesn't the compiler figure out what I want it to do?
The short answer to that is that the compiler refuses to guess.
What you want to happen would lead to impossible situations. For example, what would happen if there was a second class which also implements ITestInterface?
class SecondTestClass: ITestInterface
{
public static implicit operator SecondTestClass(string url)
{
return new SecondTestClass(url);
}
public SecondTestClass(string url)
{
Value = GetValueFromTheInternet(url);
}
public string Value { get; set; }
}
Let's re-evaluate your code:
//1
TestClass a = "This works fine.";
This works. There is a conversion from string to TestClass.
//2
SecondTestClass b = "This works fine.";
This works. There is a conversion from string to SecondTestClass.
//3
ITestInterface i = "This still doesn't work!";
//4
DoSomething("This doesn't work for the same reason as //3");
This doesn't work. The compiler does not have any known conversion from string to ITestInterface.
The compiler is unable to figure out if you want this to be converted to a TestClass and then assigned to i, or if you want this to be converted to a SecondTestClass and then assigned to i.
And, as I said before, the compiler refuses to guess.
Also, just for clarity, this would work:
TestClass a = "This works fine.";
ITestInterface i1 = a;
DoSomething(a);
DoSomething(i1);
SecondTestClass b = "This works fine.";
ITestInterface i2 = b;
DoSomething(b);
DoSomething(i2);
All of these assignations work.
The crux of your problem is that the compiler wants you to explicitly state which type you want the string to be converted to. In your own example, you were already explicitly asking for a TestClass. Notice that this would not have worked if you had used var, as the compiler would not be able to figure it out in that case either.
Pretty clear from the compiler-error, isn´t it? DoSomething expects an instance of ITestInterface, which string does not implement. The fact that there is an implicit conversion from string to your class doesn´t make this conversion also applicable for any other class implementing the interface.
Imagine there was another class implementing the interface:
class AnotherTestClass : ITestInterface { }
how would the DoSomething-call now be resolved? To which class should the conversion apply? To an instance of TestClass or to AnotherTestClass? In particular if AnotherClass also has an implicit cast-operator defined. That´s why this does not work.
Or consider the other way round: when you have only the interface but no class at all that implements it (which is pretty common when you design an API), there is no conversion at all. Your design introduces some static binding from an interface to a concrete implementation of it, which is a bad thing. In fact that makes your DoSomething-method only work for instances of type TestClass, which contradicts the use of an interface as parameter. So however uses your API can use only ever provide an instance of TestClass to your method.
Apart from this I doubt a cast is a good thing here. By having an implicit concversion you imply that every string can safely be converted to your class without losing any information. E.g. is an URI a valid representation of your class? Or even your provided "Why doesn't this work?"?
On the other side a constructor that expects a string is far more precise and makes it clear:
var m = new TestClass(myString);
From my experience there are only some very few cases where you really need an implicit cast. What you do far more often is to create some instance based upon some input and append some more data to that instance. In your example that means that a TestClass consists of some string-information, but may also have some more data.
public void DoSomething(ITestInterface thing) { }
Because the parameter is an interface and you want to call static implicit operator TestClass(string value) but it is impossible. The interface in C# can not have static method.
You can pass a class TestClass as a parameter only
public static void DoSomething(TestClass thing) { Console.WriteLine(thing.Value); }

C# Overwrite methods or Overwrite accessors for constant return

Hello.
I have a class hierarchy. Classes are read from a binary file. They are distinguished by a code that is at the beginning of their binary encoding. I want to use that code to distinguish them.
I wondered what would be the best choice for each class to return its type, overwrite a method or overwrite an accessor.
Let me give an example in which 3 classes inherit from an abstract class... a chunk of code speaks a thousand words.
// ENUM WITH TYPE CODES
enum CONCRETE_CLASS_TYPE : byte
{
CONCRETE_0 = 0xCA,
CONCRETE_1 = 0xFE,
CONCRETE_2 = 123
}
// OPTION A: OVERRIDE METHODS
abstract class AbstractClass
{
public abstract CONCRETE_CLASS_TYPE type();
}
class ConcreteClass0 : AbstractClass
{
public override CONCRETE_CLASS_TYPE type()
{
return CONCRETE_CLASS_TYPE.CONCRETE_0;
}
}
class ConcreteClass1 : AbstractClass
{
public override CONCRETE_CLASS_TYPE type()
{
return CONCRETE_CLASS_TYPE.CONCRETE_1;
}
}
class ConcreteClass2 : AbstractClass
{
public override CONCRETE_CLASS_TYPE type()
{
return CONCRETE_CLASS_TYPE.CONCRETE_2;
}
}
// OPTION B: OVERRIDE ACCESSORS
abstract class AbstractClass
{
public abstract CONCRETE_CLASS_TYPE type {get;}
}
class ConcreteClass0 : AbstractClass
{
public override CONCRETE_CLASS_TYPE type
{
get { return CONCRETE_CLASS_TYPE.CONCRETE_0; }
}
}
class ConcreteClass1 : AbstractClass
{
public override CONCRETE_CLASS_TYPE type
{
get { return CONCRETE_CLASS_TYPE.CONCRETE_1; }
}
}
class ConcreteClass2 : AbstractClass
{
public override CONCRETE_CLASS_TYPE type
{
get { return CONCRETE_CLASS_TYPE.CONCRETE_2; }
}
}
What would be the advantages and disadvantages?
The advantage I've seen to overwrite methods is that the code would be more easily translated into other languages if it did by hand.
The advantage I've seen in use accessors is spare write 2 parentheses whenever I need to know the type and that is semantically more correct.
What other advantages or disadvantages you see in the options? Is one more efficient than the other?
Thank you.
EDIT
Maybe use methods is more faster, because all things we can do with the accessors (Like parsing a JSON) must have a cost, and methods can only be "called".
Both are bad solutions as both indulge in diffusion of responsibility. You have spread the responsibilty for determining a class from an enum and four classes.
Instead, have a factory class that is responsible for providing a class type based on the code. In crude terms, the code might be:
Type GetTypeBasedonCode(int code)
{
if (code == 0xCA)
{
return typeof(ConcreteType0);
}
if (code == 0xFE)
{
return typeof(ConcreteType1);
}
return typeof(ConcreteType2);
}
There are better ways of implementing such a factory, but the key is that code/type matching is in one place, making it easier to read, understand and maintain.
In my opinion there is no advantage really, if you need to pass parameters or need to do a lengthy calculation then use a function, but if you're returning or setting a local variable that is private and you need to run a check before setting or getting the variable use a property, that is my viewing of using properties or functions
Another question like this is here When to use properties instead of functions
[Question answered by : Reed Copsey]
When using properties thing if the property will :
return a single, logic value
Little or no logic is involved (typically just return a value, or do a small check/return value)
When to use functions think of if the result value will require :
There is going to be significant work involved in returning the value - ie: it'll get fetched from a DB, or something that may take "time"
There is quite a bit of logic involved, either in getting or setting the value
In addition, I'd recommend looking at Microsoft's Design Guidelines for Property Usage. They suggest:
Use a property when the member is a logical data member.
Use a method when:
The operation is a conversion, such as Object.ToString.
The operation is expensive enough that you want to communicate to the user that they should consider caching the result.
Obtaining a property value using the get accessor would have an observable side effect.
Calling the member twice in succession produces different results.
The order of execution is important. Note that a type's properties should be able to be set and retrieved in any order.
The member is static but returns a value that can be changed.
The member returns an array. Properties that return arrays can be very misleading. Usually it is necessary to return a copy of the internal array so that the user cannot change internal state. This, coupled with the fact that a user can easily assume it is an indexed property, leads to inefficient code. In the following code example, each call to the Methods property creates a copy of the array. As a result, 2n+1 copies of the array will be created in the following loop.

How could I declare list of generics with different and unknown types and How could I initialize a generic with a type only known at runtime?

This is a 2 part question.
Firstly
I have a class called ComponentList that looks like this:
public class ComponentList<T> : List<T> where T : Component
{
}
Now I want to create an empty list of typeless ComponentLists:
List<ComponentList<>> MasterList = new List<ComponentList<>>();
I get an error because the ComponentList wants a generic type specified even though I'm not trying to initialize any ComponentLists yet (just the MasterList that contains them). How would I declare the MasterList of ComponentLists without initializing any ComponentLists (as I plan to initialize them during runtime with types only known at runtime)? After all, the MasterList needs to contain ComponentLists of different generic types, not just one.
Secondly
I know this one has been asked before, but I can't seem to wrap my head around the concepts of any of the proposed solutions.
As you know, I have a List<> called MasterList which is a list of ComponentLists (a custom class). A ComponentList is a generic class of an undefined type (that is constrained to being a subtype of Component).
In the following example, I'm trying to check if a ComponentList generic type (referenced from MasterList) is the same as this class (the class the code's being called from).
if (MasterList[i].GetType() == typeof(ComponentList<this.GetType()>))
{
}
Problem is, the code is meant to be automatically called from unknown child classes, not from this parent class. So the ComponentList generic type needs to be compared with the type of the child class, not this base class. Hence the "this.GetType" inplace of what would be the hardcoded name of the actual base class.
The this.GetType() type passed in the ComponentList<> returns a "type expected" error apparently because GetType() returns compile time type, not runtime type (which is what I need).
So how could I get the runtime type? And if I can't, what would be the best alternative to accomplishing what I'm trying to do? (I've heard a bit about something called reflections that might help me but I really don't understand).
You cannot determine generic types at runtime. C# (all .Net, actually) is designed that way on purpose. The compiler treats a generic type virtually same way as an explicitly defined type.
Consider the following:
class MyGenericClass<T>
{
public static T MyProperty { get; set; }
}
class MyIntClass
{
public static int MyProperty { get; set; }
}
class UseThem
{
public void test()
{
// both are JIT'ed to be exactly the same machine code
var foo = MyGenericClass<int>.MyProperty;
var bar = MyOtherClass.MyProperty;
}
}
Thus, you must provide a type for the generic class so that JIT knows what to compile.
Possible Alternative
If all of the possible types which could possible end up being the generic type are similar (inherit from the same base class or implement a similar interface), then you can instantiate the generic class with an interface or base class as the generic type:
List<ComponentList<ComponentBase>> MasterList = new List<ComponentList<ComponentBase>>();
// -OR-
List<ComponentList<IMyComponent>> MasterList = new List<ComponentList<IMyComponent>>();
I have a hunch that you should be able to define a common interface or base class with a little creative refactoring. :)
I've run into this issue as well when I was trying to set up an entity-component system for a game written in C#. There's really isn't a way to store components as their actual types, you have to store them all as Components and cast them.
The way I have it set up is as a Dictionary<Type, List<Component>> as a private member of a ComponentManager class. The method that adds components is generic and checks if it's Type is contained in the Dictionary, so getting an IEnumerable<SpecificComponent> is as simple as:
public IEnumerable<T> EnumerateComponents<T>()
where T : Component
{
foreach (Component c in components[typeof(T)])
yield return (T)c;
}
(You'll also want to check that the dictionary contains typeof(T), that bit is built-in with a custom collection of mine that inherits from Dictionary to avoid exceptions in cases like this.)
Type safety is "guaranteed" as long as the dictionary is never modified outside of a generic method (and definitely not directly accessible from the outside). Not ideal, but it's fast enough where it will never be your bottleneck.
EDIT
Something to explore might be C# 4's dynamic keyword. I haven't looked into it much, but storing the components as a List<dynamic> might work better (or it may introduce way too much overhead), just something to think about.
I don't think what you are asking is possible, however maybe this is what you need.
public class ComponentA : Component { }
public class ComponentB : Component { }
public class Component { }
public class ComponentList<T> : List<T> where T : Component
{
}
class Program
{
static void Main(string[] args)
{
ComponentList<Component> MasterList = new ComponentList<Component>();
MasterList.Add(new ComponentA());
MasterList.Add(new ComponentB());
for (int i = 0; i < MasterList.Count; i++)
{
if (MasterList[i] is ComponentA)
{
}
}
}
}

Double-dispatch and alternatives

I am trying to find a better way to handle some growing if constructs to handle classes of different types. These classes are, ultimately, wrappers around disparate value types (int, DateTime, etc) with some additional state information. So the primary difference between these classes is the type of data they contain. While they implement generic interfaces, they also need to be kept in homogeneous collections, so they also implement a non-generic interface. The class instances are handled according to the type of data they represent and their propogation continues or doesn't continue based on that.
While this is not necessarily a .NET or C# issue, my code is in C#.
Example classes:
interface ITimedValue {
TimeSpan TimeStamp { get; }
}
interface ITimedValue<T> : ITimedValue {
T Value { get; }
}
class NumericValue : ITimedValue<float> {
public TimeSpan TimeStamp { get; private set; }
public float Value { get; private set; }
}
class DateTimeValue : ITimedValue<DateTime> {
public TimeSpan TimeStamp { get; private set; }
public DateTime Value { get; private set; }
}
class NumericEvaluator {
public void Evaluate(IEnumerable<ITimedValue> values) ...
}
I have come up with two options:
Double Dispatch
I recently learned of the Visitor pattern and its use of double dispatch to handle just such a case. This appeals because it would allow undesired data to not propogate (if we only want to handle an int, we can handle that differently than a DateTime). Also, the behaviors of how the different types are handled would be confined to the single class that is handling the dispatch. But there is a fair bit of maintenance if/when a new value type has to be supported.
Union Class
A class that contains a property for each value type supported could be what each of these classes store. Any operation on a value would affect the appropriate component. This is less complex and less maintenance than the double-dispatch strategy, but it would mean that every piece of data would propogate all the way through unnecessarily as you can no longer discriminate along the lines of "I don't operate upon that data type". However, if/when new types need to be supported, they only need to go into this class (plus whatever additional classes that need to be created to support the new data type).
class UnionData {
public int NumericValue;
public DateTime DateTimeValue;
}
Are there better options? Is there something in either of these two options that I did not consider that I should?
method 1, using dynamic for double dispatch (credit goes to http://blogs.msdn.com/b/curth/archive/2008/11/15/c-dynamic-and-multiple-dispatch.aspx).
Basically you can have your Visitor pattern simplified like this:
class Evaluator {
public void Evaluate(IEnumerable<ITimedValue> values) {
foreach(var v in values)
{
Eval((dynamic)(v));
}
}
private void Eval(DateTimeValue d) {
Console.WriteLine(d.Value.ToString() + " is a datetime");
}
private void Eval(NumericValue f) {
Console.WriteLine(f.Value.ToString() + " is a float");
}
}
sample of usage:
var l = new List<ITimedValue>(){
new NumericValue(){Value= 5.1F},
new DateTimeValue() {Value= DateTime.Now}};
new Evaluator()
.Evaluate(l);
// output:
// 5,1 is a float
// 29/02/2012 19:15:16 is a datetime
method 2 would use Union types in c# as proposed by #Juliet here (alternative implementation here)
I tell you have I've solved a similar situation - is by storing the Ticks of a DateTime or TimeSpan as double in the collection and by using IComparable as a where constraint on the type parameter. The conversion to double / from double is performed by a helper class.
Please see this previous question.
Funnily enough this leads to other problems, such as boxing and unboxing. The application I am working on requires extremely high performance so I need to avoid boxing. If you can think of a great way to generically handle different datatypes (including DateTime) then I'm all ears!
Good question. The first thing that came to my mind was a reflective Strategy algorithm. The runtime can tell you, either statically or dynamically, the most derived type of the reference, regardless of the type of the variable you are using to hold the reference. However, unfortunately, it will not automatically choose an overload based on the derived type, only the variable type. So, we need to ask at runtime what the true type is, and based on that, manually select a particular overload. Using reflection, we can dynamically build a collection of methods identified as handling a particular sub-type, then interrogate the reference for its generic type and look up the implementation in the dictionary based on that.
public interface ITimedValueEvaluator
{
void Evaluate(ITimedValue value);
}
public interface ITimedValueEvaluator<T>:ITimedValueEvaluator
{
void Evaluate(ITimedValue<T> value);
}
//each implementation is responsible for implementing both interfaces' methods,
//much like implementing IEnumerable<> requires implementing IEnumerable
class NumericEvaluator: ITimedValueEvaluator<int> ...
class DateTimeEvaluator: ITimedValueEvaluator<DateTime> ...
public class Evaluator
{
private Dictionary<Type, ITimedValueEvaluator> Implementations;
public Evaluator()
{
//find all implementations of ITimedValueEvaluator, instantiate one of each
//and store in a Dictionary
Implementations = (from t in Assembly.GetCurrentAssembly().GetTypes()
where t.IsAssignableFrom(typeof(ITimedValueEvaluator<>)
and !t.IsInterface
select new KeyValuePair<Type, ITimedValueEvaluator>(t.GetGenericArguments()[0], (ITimedValueEvaluator)Activator.CreateInstance(t)))
.ToDictionary(kvp=>kvp.Key, kvp=>kvp.Value);
}
public void Evaluate(ITimedValue value)
{
//find the ITimedValue's true type's GTA, and look up the implementation
var genType = value.GetType().GetGenericArguments()[0];
//Since we're passing a reference to the base ITimedValue interface,
//we will call the Evaluate overload from the base ITimedValueEvaluator interface,
//and each implementation should cast value to the correct generic type.
Implementations[genType].Evaluate(value);
}
public void Evaluate(IEnumerable<ITimedValue> values)
{
foreach(var value in values) Evaluate(value);
}
}
Notice that the main Evaluator is the only one that can handle an IEnumerable; each ITimedValueEvaluator implementation should handle values one at a time. If this isn't feasible (say you need to consider all values of a particular type), then this gets really easy; just loop through every implementation in the Dictionary, passing it the full IEnumerable, and have those implementations filter the list to only objects of the particular closed generic type using the OfType() Linq method. This will require you to run all ITimedValueEvaluator implementations you find on the list, which is wasted effort if there are no items of a particular type in a list.
The beauty of this is its extensibility; to support a new generic closure of ITimedValue, just add a new implementation of ITimedValueEvaluator of the same type. The Evaluator class will find it, instantiate a copy, and use it. Like most reflective algorithms, it's slow, but the actual reflective part is a one-time deal.
Why not just implement the interface that you actually want, and allow the implementing type to define what the value is? For example:
class NumericValue : ITimedValue<float> {
public TimeSpan TimeStamp { get; private set; }
public float Value { get; private set; }
}
class DateTimeValue : ITimedValue<DateTime>, ITimedValue<float> {
public TimeSpan TimeStamp { get; private set; }
public DateTime Value { get; private set; }
public Float ITimedValue<Float>.Value { get { return 0; } }
}
class NumericEvaluator {
public void Evaluate(IEnumerable<ITimedValue<float>> values) ...
}
If you want the behavior of the DateTime implementation to vary based on the particular usage (say, alternate implementations of Evaluate functions), then they by definition need to be aware of ITimedValue<DateTime>. You can get to a good statically-typed solution by providing one or more Converter delegates, for example.
Finally, if you really only want to handle the NumericValue instances, just filter out anything that isn't a NumericValue instance:
class NumericEvaluator {
public void Evaluate(IEnumerable<ITimedValue> values) {
foreach (NumericValue value in values.OfType<NumericValue>()) {
....
}
}
}

Why does C# not allow generic properties?

I was wondering why I can not have generic property in non-generic class the way I can have generic methods. I.e.:
public interface TestClass
{
IEnumerable<T> GetAllBy<T>(); //this works
IEnumerable<T> All<T> { get; } //this does not work
}
I read #Jon Skeet's answer, but it's just a statement, which most probably is somewhere in the specifications.
My question is why actually it is that way? Was kind of problems were avoided with this limitation?
Technically, the CLR supports only generic types and methods, not properties, so the question is why it wasn’t added to the CLR. The answer to that is probably simply “it wasn’t deemed to bring enough benefit to be worth the costs”.
But more fundamentally, it was deemed to bring no benefit because it doesn’t make sense semantically to have a property parameterised by a type. A Car class might have a Weight property, but it makes no sense to have a Weight<Fruit> and a Weight<Giraffe> property.
This Generic Properties blog post from Julian Bucknall is a pretty good explanation. Essentially it's a heap allocation problem.
My guess is that it has some nasty corner cases that make the grammar ambiguous. Off-hand, this seems like it might be tricky:
foo.Bar<Baz>=3;
Should that be parsed as:
foo.Bar<Baz> = 3;
Or:
foo.Bar < Baz >= 3;
I think not using an automatic getter/setter illustrates why this isn't possible without having "T" defined at the class level.
Try coding it, the natural thing to do would be this:
IEnumerable<T> _all;
IEnumerable<T> All
{
get { return _all; }
}
Because your field uses "T", then "T" needs to be on the class the CLR knows what "T" is.
When you're using a method, you can delay definition of "T" until you actually call the method. But with the field/property, "T" needs to be declared in one place, at the class level.
Once you declare T on the class, creating a property becomes pretty easy.
public class TestClass<T>
{
IEnumerable<T> All { get; }
}
usage:
var myTestClass = new TestClass<string>();
var stuff = myTestClass.All;
And just like the "T" type parameter on a method, you can wait until you actually instantiate your TestClass to define what "T" will be.
I made somthing like that.
It type checks at run time.
public class DataPackage
{
private dynamic _list;
public List<T> GetList<T>()
{
return (List<T>)_list;
}
public void SetList<T>(List<T> list)
{
_list = list;
}
public string Name { get; set; }
}

Categories

Resources